为了避免污染宿主系统环境,于是在虚拟机中搭建了一个linux环境并且安装了rabbitmq-server。然后在远程连接的时候一直连接失败。官网上面给的例子都是在本地使用系统默认的guest用户连接的。没有给出远程连接的例子,于是阅读文档发现:
When the serverfirst starts running, and detects that its database is uninitialised or hasbeen deleted, it initialises a fresh database with the following resources:
a virtual hostnamed /
a user namedguest with a default password of guest, granted full access to the / virtualhost.
也就是刚刚安装好rabbitmq-server,系统会自动创建一个名为“/”的virtual host,同时也会创建一个用户名和密码都是guest的用户,并且应用"/ virtual host"的所有访问权限。因此在rabbitmq安装的机器上使用官网给出的例子:
public class Send {
// 队列名称
privatefinal static String QUEUE_NAME = "hello";
publicstatic void main(String[] argv) throws java.io.IOException {
/**
* 创建连接连接到MabbitMQ
*/
ConnectionFactoryfactory = new ConnectionFactory();
// 设置MabbitMQ所在主机ip或者主机名
factory.setHost("localhost");
// 创建一个连接
Connectionconnection = factory.newConnection();
// 创建一个频道
Channelchannel = connection.createChannel();
// 指定一个队列
channel.queueDeclare(QUEUE_NAME,false, false, false, null);
// 发送的消息
Stringmessage = "hello world!";
// 往队列中发出一条消息
channel.basicPublish("",QUEUE_NAME, null, message.getBytes());
System.out.println("[x] Sent '" + message + "'");
// 关闭频道和连接
channel.close();
connection.close();
}
}
运行是没问题的。如果要切换到远程机器访问的话,单纯的修改factory.setHost("localhost")是不行的。因为guest用户只是被容许从localhost访问。官网文档描述如下:
"guest" user can only connect via localhost
By default, theguest user is prohibited from connecting to the broker remotely; it can onlyconnect over a > loopback interface (i.e. localhost). This applies both toAMQP and to any other protocols enabled via plugins. Any > other users youcreate will not (by default) be restricted in this way.
This isconfigured via the loopback_users item in the configuration file.
If you wish toallow the guest user to connect from a remote host, you should set theloopback_users configuration item to []. A complete rabbitmq.config which doesthis would look like:
默认情况下,使用下面的命令:
rabbitmqctl environment
会发现:
我现在不想使用默认的guest用户,我新建立了一个用户test,然后授予所有权限,使用下面的命令:
rabbitmqctl add_user test 123456
rabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test ".*"".*" ".*"
创建用户
为用户设置角色
为用户设置权限
这种方式设置的默认的“/”权限,还可以自己添加其它权限
rabbitmqctl add_vhost vhost_test
然后使用下面的代码远程访问
public class Send2 {
// 队列名称
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws java.io.IOException {
/**
* 创建连接连接到MabbitMQ
*/
ConnectionFactory factory = new ConnectionFactory();
// 设置MabbitMQ所在主机ip或者主机名
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("test");
factory.setPassword("123456");
factory.setVirtualHost("vhost_test");
// 创建一个连接
Connection connection = factory.newConnection();
// 创建一个频道
Channel channel = connection.createChannel();
// 指定一个队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 发送的消息
String message = "hello world!";
// 往队列中发出一条消息
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
// 关闭频道和连接
channel.close();
connection.close();
}
}
public class Recv2 {
// 队列名称
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws java.io.IOException,
ShutdownSignalException, ConsumerCancelledException,
InterruptedException {
// 打开连接和创建频道,与发送端一样
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("test");
factory.setPassword("123456");
factory.setVirtualHost("vhost_test");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明队列,主要为了防止消息接收者先运行此程序,队列还不存在时创建队列。
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
// 创建队列消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
// 指定消费队列
channel.basicConsume(QUEUE_NAME, true, consumer);
while (true) {
// nextDelivery是一个阻塞方法(内部实现其实是阻塞队列的take方法)
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
}
}
输出:
[*] Waiting for messages. To exit press CTRL+C
[x] Received 'hello world!'
这次连接成功,测试通过