RabbitMQ(四)遠端連線RabbitMQ
阿新 • • 發佈:2019-02-11
為了避免汙染宿主系統環境,於是在虛擬機器中搭建了一個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!'
這次連線成功,測試通過