在RabbitMQ中有一個vhost的概念,vhost就相當於一個個MINI版的RabbitMQ服務器,在一個RabbitMQ服務器上可以創建多個vhost,他們有自己的權限控制機制,我們可以讓不同的用戶擁有訪問不同vhost的權限。更簡單的說就好像一個操作系統上運行的多個虛擬機。
我們可以用rabbitmqctl list_vhosts來查看當前RabbitMQ服務器上已有的vhost。當前我們的服務器上只有一個名叫“/”的vhost,這個也是RabbitMQ默認的vhost。
接下來我們用rabbitmqctl add_vhost來添加一個vhost。
添加新的vhost後,我們還無法訪問這個vhost,需要用rabbitmqctl set_permissions給用戶訪問該vhost的權限。
然後我們就可以訪問這個新創建的vhost了,我們把以前的代碼稍微修改下:
package com.jaeger.vhost; import java.io.IOException; import java.util.concurrent.TimeoutException; import org.junit.Test; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Consumer; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; public class Producer { private static final String MY_EXCHANGE_NAME = "MyExchange"; private static final String MY_ROUTING_KEY = "MyRoutingKey"; private static final String MY_QUEUE_NAME = "MyQueue"; private static final String DIRECT = "direct"; private static final String HOST = "172.19.64.28"; private static final String USER = "jaeger"; private static final String PASSWORD = "root"; private static final String VHOST = "jaeger_vhost"; private static final int PORT = 5672; @Test public void createExchangeAndQueue() throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost(HOST); connectionFactory.setUsername(USER); connectionFactory.setPassword(PASSWORD); connectionFactory.setPort(PORT); // 指定需要訪問的vhost名稱 connectionFactory.setVirtualHost(VHOST); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(MY_EXCHANGE_NAME, DIRECT); channel.queueDeclare(MY_QUEUE_NAME, false, false, false, null); channel.queueBind(MY_QUEUE_NAME, MY_EXCHANGE_NAME, MY_ROUTING_KEY); channel.close(); connection.close(); } @Test public void produce() throws IOException, TimeoutException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost(HOST); connectionFactory.setUsername(USER); connectionFactory.setPassword(PASSWORD); connectionFactory.setPort(PORT); // 指定需要訪問的vhost名稱 connectionFactory.setVirtualHost(VHOST); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); String message = "Hello 世界!"; channel.basicPublish(MY_EXCHANGE_NAME, MY_ROUTING_KEY, null, message.getBytes("utf-8")); System.out.println("Sent '" + message + "'"); channel.close(); connection.close(); } @Test public void consume() throws IOException, TimeoutException, InterruptedException { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost(HOST); connectionFactory.setUsername(USER); connectionFactory.setPassword(PASSWORD); connectionFactory.setPort(PORT); // 指定需要訪問的vhost名稱 connectionFactory.setVirtualHost(VHOST); Connection connection = connectionFactory.newConnection(); Channel channel = connection.createChannel(); Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println("Received '" + message + "'"); } }; channel.basicConsume(MY_QUEUE_NAME, true, consumer); Thread.sleep(1000); } }
首先運行createExchangeAndQueue方法,在jaeger_vhost下創建新的exchange和queue:
再運行produce方法向jaeger_vhost的queue裏添加一條數據: