RabbitMQ系列之三:publish subscribe
server端代码:
1 package com.example.publishsubscribe; 2 3 import java.io.IOException; 4 5 import com.rabbitmq.client.Channel; 6 import com.rabbitmq.client.Connection; 7 import com.rabbitmq.client.ConnectionFactory; 8 9 public class Send { 10 11 // 定义一个logs的邮局,对消息进行分发处理 12 private static final String EXCHANGE_NAME = "logs"; 13 14 public static void main(String[] args) throws IOException { 15 16 ConnectionFactory factory = new ConnectionFactory(); 17 18 //远程服务器ip,如果在本地测试可以改成localhost 19 factory.setHost("121.40.151.120"); 20 21 //不是在本地测试,用户名和密码必填 22 factory.setUsername("rabbitmqtest"); 23 factory.setPassword("rabbitmqtest"); 24 25 Connection conn = factory.newConnection(); 26 Channel channel = conn.createChannel(); 27 28 /** 29 * 参数说明: 30 * exchange:邮局名称 31 * type: 32 * direct: 通过routingKey和exchange决定的那个唯一的queue可以接收消息。 33 * 它会处理routingKey,需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。 34 * 这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “dog”,则只有被标记为“dog”的消息才被转发, 35 * 不会转发dog.puppy,也不会转发dog.guard,只会转发dog。 36 * topic: 所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息。 37 * 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。 38 * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。 39 * fanout: 所有bind到此exchange的queue都可以接收消息。 40 * 不会处理routingKey。你只需要简单的将队列绑定到交换机上。 41 * 一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。 42 * 很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。 43 * 44 */ 45 channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); 46 47 String message = getMessage(new String[] { "test" }); 48 49 /** 50 * 参数说明: 51 * exchange:默认的exchange就是"",是direct类型的, 52 * 任何发往到默认exchange的消息都会被路由到routingKey的名字对应的队列上,如果没有对应的队列,则消息会被丢弃。 53 * routingKey:因为这里的exchange类型是fanout的,所以会匹配所有的routingKey。 54 * props:其它属性,比如消息路由头信息,持久化信息 55 * body:消息内容 56 */ 57 channel.basicPublish(EXCHANGE_NAME, "anyRoutingKey", null, message.getBytes()); 58 59 System.out.println("send[" + message + "]"); 60 61 // 最后,我们关闭channel和连接,释放资源。 62 channel.close(); 63 conn.close(); 64 } 65 66 private static String getMessage(String[] strings) { 67 if (strings.length < 1) { 68 return "Hello World!"; 69 } 70 return joinStrings(strings, " "); 71 } 72 73 private static String joinStrings(String[] strings, String delimiter) { 74 int length = strings.length; 75 if (length == 0) { 76 return ""; 77 } 78 StringBuilder words = new StringBuilder(strings[0]); 79 for (int i = 1; i < length; i++) { 80 words.append(delimiter).append(strings[i]); 81 } 82 return words.toString(); 83 } 84 85 }
client端代码:
1 package com.example.workqueue; 2 3 import java.io.IOException; 4 5 import com.rabbitmq.client.Channel; 6 import com.rabbitmq.client.Connection; 7 import com.rabbitmq.client.ConnectionFactory; 8 import com.rabbitmq.client.ConsumerCancelledException; 9 import com.rabbitmq.client.QueueingConsumer; 10 import com.rabbitmq.client.ShutdownSignalException; 11 12 public class Recv { 13 14 private static final String EXCHANGE_NAME = "logs"; 15 16 public static void main(String[] args) throws IOException, ShutdownSignalException, 17 ConsumerCancelledException, InterruptedException { 18 19 ConnectionFactory factory = new ConnectionFactory(); 20 21 factory.setHost("121.40.151.120"); 22 factory.setUsername("rabbitmqtest"); 23 factory.setPassword("rabbitmqtest"); 24 25 Connection connection = factory.newConnection(); 26 Channel channel = connection.createChannel(); 27 channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); 28 29 // 临时队列(temporary queue) 30 // 首先,无论什么时候连接Rabbit时,我们需要一个新的、空的队列 31 // First, whenever we connect to Rabbit we need a fresh, empty queue. 32 // 为了做到这一点,我们可以创建一个随机命名的队列,或者更好的,就让服务端给我们选择一个随机的队列名字。 33 // 其次,一旦我们关闭消费者的连接,这个临时队列应该自动销毁。 34 String queueName = channel.queueDeclare().getQueue(); 35 // routingKey这里是没有任何作用的,也就是名字可以随便取 36 channel.queueBind(queueName, EXCHANGE_NAME, "anyRoutingKey2"); 37 38 System.out.println("CRTL+C"); 39 40 // QueueingConsumer:用来缓存服务端推送给我们的消息。 41 QueueingConsumer consumer = new QueueingConsumer(channel); 42 channel.basicConsume(queueName, true, consumer); 43 44 while (true) { 45 QueueingConsumer.Delivery delivery = consumer.nextDelivery(); 46 String message = new String(delivery.getBody()); 47 System.out.println("[" + message + "]"); 48 } 49 } 50 51 }
三种Exchange的图解:
direct exchange:

fanout exchange:

topic exchange:

浙公网安备 33010602011771号