1. 程式人生 > >RabbitMQ(四)遠端連線RabbitMQ

RabbitMQ(四)遠端連線RabbitMQ

為了避免汙染宿主系統環境,於是在虛擬機器中搭建了一個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!'

這次連線成功,測試通過