接着上篇
-
pubsub发布订阅模式
一个生产者通过交换机发布到队列中再分别传输给消费者。即生产者P发出的消息传输到交换机,交换机再分发给绑定在它身上的队列,再发送给消费者,C1和C2都会接收到。交换机类型为Fanout(广播型)。
建立一个Producer和多个Consumer 来模拟一个Producer发送天气信息 分别分发到消费端。package com.orange.rabbitmq.pubsub; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.io.IOException; import java.util.Scanner; import java.util.concurrent.TimeoutException; /** * @description 生产者 */ public class Producer { public static void main(String[] args) throws IOException, TimeoutException { // 获取链接 Connection connection = RabbitMQUtils.getConnection(); // 创建传输通道 final Channel channel = connection.createChannel(); String msg = "北京天气:0~-4"; // 生产者只需指定交换机即可,此时无需绑定队列 channel.basicPublish(MQConstant.MQ_EXCHANGE_PUBSUB_NAME, "", null, msg.getBytes()); channel.close(); connection.close(); System.out.println("消息发送完成,链接关闭"); } }
package com.orange.rabbitmq.pubsub; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * @description 消费者Sina */ public class Sina { public static void main(String[] args) throws IOException { Connection connection = RabbitMQUtils.getConnection(); final Channel channel = connection.createChannel(); // 声明队列 channel.queueDeclare(MQConstant.MQ_QUEUE_SINA, false, false, false, null); // 将队列绑定到指定交换机 channel.queueBind(MQConstant.MQ_QUEUE_SINA, MQConstant.MQ_EXCHANGE_PUBSUB_NAME, ""); // 消费完一条消息再去MQ Server请求下一条 channel.basicQos(1); channel.basicConsume(MQConstant.MQ_QUEUE_SINA, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String msg = new String(body); System.out.println("Sina获取天气信息:" + msg); channel.basicAck(envelope.getDeliveryTag(), false); } }); } }
package com.orange.rabbitmq.pubsub; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * @description 消费者Baidu */ public class Baidu { public static void main(String[] args) throws IOException { Connection connection = RabbitMQUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(MQConstant.MQ_QUEUE_BAIDU, false, false, false, null); // 队列绑定指定交换机 channel.queueBind(MQConstant.MQ_QUEUE_BAIDU, MQConstant.MQ_EXCHANGE_PUBSUB_NAME, ""); channel.basicQos(1); channel.basicConsume(MQConstant.MQ_QUEUE_BAIDU, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String msg = new String(body); System.out.println("Baidu获取天气信息:" + msg); channel.basicAck(envelope.getDeliveryTag(), false); } }); } }
依次启动运行Sina、Baidu,再运行Producer,看到Consumer打印出的日志 即表示签收消息成功
-
Routing路由模式
routing路由模式和发布订阅模式基本一样,只是在交换机分发给队列时增加一定条件。队列可定义自己的接收规则(==)。交换机分发给队列时,会判断是否满足条件,满足才会发放。交换机类型为Direct(定向型)
建立一个Producer和2个Consumer 来模拟一个Producer发送信息 通过区分不同规则分别分发到对应消费端。package com.orange.rabbitmq.routing; import com.google.gson.Gson; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.io.IOException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.concurrent.TimeoutException; /** * @description 生产者 */ public class Producer { public static void main(String[] args) throws IOException, TimeoutException { Map<String, String> map = new LinkedHashMap(); map.put("china.hunan.changsha.20201127", "中国湖南长沙20201127天气数据"); map.put("china.hubei.wuhan.20201127", "中国湖北武汉20201127天气数据"); map.put("china.hunan.zhuzhou.20201127", "中国湖南株洲20201127天气数据"); map.put("us.cal.lsj.20201127", "美国加州洛杉矶20201127天气数据"); map.put("china.hebei.shijiazhuang.20201128", "中国河北石家庄20201128天气数据"); map.put("china.hubei.wuhan.20201128", "中国湖北武汉20201128天气数据"); map.put("china.henan.zhengzhou.20201128", "中国河南郑州20201128天气数据"); map.put("us.cal.lsj.20201128", "美国加州洛杉矶20201128天气数据"); // 获取链接 Connection connection = RabbitMQUtils.getConnection(); // 创建传输通道 Channel channel = connection.createChannel(); for (String key : map.keySet()) { // 发布消息并写入消息的key channel.basicPublish(MQConstant.MQ_EXCHANGE_ROUTING_NAME, key, null, map.get(key).getBytes()); } channel.close(); connection.close(); System.out.println("消息发送完成,链接关闭"); } }
package com.orange.rabbitmq.routing; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * @description 消费者 */ public class Sina { public static void main(String[] args) throws IOException { Connection connection = RabbitMQUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(MQConstant.MQ_QUEUE_SINA, false, false, false, null); // 将队列绑定到交换机上,并指定消息接收routing规则,即key等于“china.hunan.changsha.20201127”的消息才会被接收 channel.queueBind(MQConstant.MQ_QUEUE_SINA, MQConstant.MQ_EXCHANGE_ROUTING_NAME, "china.hunan.changsha.20201127"); channel.basicQos(1); channel.basicConsume(MQConstant.MQ_QUEUE_SINA, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("新浪收到一条消息:" + new String(body)); channel.basicAck(envelope.getDeliveryTag(), false); } }); } }
package com.orange.rabbitmq.routing; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * @description 消费者 */ public class Baidu { public static void main(String[] args) throws IOException { Connection connection = RabbitMQUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(MQConstant.MQ_QUEUE_BAIDU, false, false, false, null); channel.queueBind(MQConstant.MQ_QUEUE_BAIDU, MQConstant.MQ_EXCHANGE_ROUTING_NAME, "us.cal.lsj.20201128"); channel.basicQos(1); channel.basicConsume(MQConstant.MQ_QUEUE_BAIDU, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String msg = new String(body); System.out.println("百度收到一条消息:" + msg); channel.basicAck(envelope.getDeliveryTag(), false); } }); } }
这个运行结果不知道是因为缓存还是什么原因一个准一个不准。但代码思路应该是没问题的。这里就先不贴图啦。要是有不对的地方,欢迎提出来指导学习。
-
Topic模式
Topic模式和Routing差不多,唯一不同就是匹配规则那里。Routing路由模式是精准匹配,Topic类似于模糊查询,可多个匹配。实现规则有两种通配符:和#。 占1位,#站多位。
通配符规则:#匹配一个或多个词,*匹配不多不少恰好1个词,
例如:item.#能够匹配 item.insert.abc 或者 item.insert;item.*只能匹配 item.insert
package com.orange.rabbitmq.topic; import com.google.gson.Gson; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.TimeoutException; /** * @author wangxinyue * @date 2020-11-30 * @description 生产者 */ public class Producer { public static void main(String[] args) throws IOException, TimeoutException { Map<String, String> map = new LinkedHashMap(); map.put("china.hunan.changsha.20201127", "中国湖南长沙20201127天气数据"); map.put("china.hubei.wuhan.20201127", "中国湖北武汉20201127天气数据"); map.put("china.hunan.zhuzhou.20201127", "中国湖南株洲20201128天气数据"); map.put("us.cal.lsj.20201127", "美国加州洛杉矶20201127天气数据"); map.put("china.hebei.shijiazhuang.20201128", "中国河北石家庄20201128天气数据"); map.put("china.hubei.wuhan.20201128", "中国湖北武汉20201128天气数据"); map.put("china.henan.zhengzhou.20201128", "中国河南郑州20201128天气数据"); map.put("us.cal.lsj.20201128", "美国加州洛杉矶20201128天气数据"); // 获取链接 Connection connection = RabbitMQUtils.getConnection(); // 创建传输通道 Channel channel = connection.createChannel(); for (String key : map.keySet()) { // 发布消息并写入消息的key channel.basicPublish(MQConstant.MQ_EXCHANGE_TOPIC_NAME, key, null, map.get(key).getBytes()); } channel.close(); connection.close(); System.out.println("消息发送完成,链接关闭"); } }
package com.orange.rabbitmq.topic; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * @description 消费者 */ public class Sina { public static void main(String[] args) throws IOException { Connection connection = RabbitMQUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(MQConstant.MQ_QUEUE_SINA, false, false, false, null); // 包含通配符的表达方式,匹配以china开头的key的数据。 channel.queueBind(MQConstant.MQ_QUEUE_SINA, MQConstant.MQ_EXCHANGE_TOPIC_NAME, "china.#"); channel.basicQos(1); channel.basicConsume(MQConstant.MQ_QUEUE_SINA, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println("新浪收到一条消息:" + new String(body)); channel.basicAck(envelope.getDeliveryTag(), false); } }); } }
package com.orange.rabbitmq.topic; import com.orange.rabbitmq.utils.MQConstant; import com.orange.rabbitmq.utils.RabbitMQUtils; import com.rabbitmq.client.*; import java.io.IOException; /** * @description 消费者 */ public class Baidu { public static void main(String[] args) throws IOException { Connection connection = RabbitMQUtils.getConnection(); final Channel channel = connection.createChannel(); channel.queueDeclare(MQConstant.MQ_QUEUE_BAIDU, false, false, false, null); channel.queueBind(MQConstant.MQ_QUEUE_BAIDU, MQConstant.MQ_EXCHANGE_TOPIC_NAME, "china.hubei.wuhan.*"); channel.basicQos(1); channel.basicConsume(MQConstant.MQ_QUEUE_BAIDU, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String msg = new String(body); System.out.println("百度收到一条消息:" + msg); channel.basicAck(envelope.getDeliveryTag(), false); } }); } }
先介绍这5种,以上。