4.rabbitmq--路由模式
rabbitmq--路由模式
想象之前的订阅发布模式: 一个生产者,多个消费者,每一个消费者都有自己的一个队列,生产者没有将消息直接发送到队列,而是发送到了交换机,每个队列绑定交换机,生产者发送的消息经过交换机,到达队列,实现一个消息被多个消费者获取的目的。
需要注意的是,如果将消息发送到一个没有队列绑定的exchange上面,那么该消息将会丢失,这是因为在rabbitMQ中exchange不具备存储消息的能力,只有队列具备存储消息的能力。
但是如果想象下这样的一个场景:生产者有新增商品,修改商品,删除商品的消息,消费者包含前台系统和搜索系统,要求前台系统接收修改和删除商品的消息,搜索系统接收新增商品、修改商品和删除商品的消息。所以使用这种订阅模式实现商品数据的同步并不合理。因此我们介绍下一种模式:路由模式。
这种模式添加了一个路由键,生产者发布消息的时候添加路由键,消费者绑定队列到交换机时添加键值,这样就可以接收到需要接收的消息。


生产者:
package com.maozw.mq.routing; import com.maozw.mq.config.RabbitConfig;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.io.IOException;
import java.util.concurrent.TimeoutException; import static org.apache.log4j.varia.ExternallyRolledFileAppender.OK; /**
* work 模式
* 两种分发: 轮询分发 + 公平分发
* 轮询分发:消费端:自动确认消息;boolean autoAck = true;
* 公平分发: 消费端:手动确认消息 boolean autoAck = false; channel.basicAck(envelope.getDeliveryTag(),false);
*
* @author MAOZW
* @Description: ${todo}
* @date 2018/11/26 15:06
*/
@RestController
@RequestMapping("/routing")
public class RoutingProducer {
private static final Logger LOGGER = LoggerFactory.getLogger(RoutingProducer.class);
@Autowired
RabbitConfig rabbitConfig; @RequestMapping("/send")
public String send() throws IOException, TimeoutException {
Connection connection = null;
Channel channel= null;
try {
ConnectionFactory connectionFactory = rabbitConfig.connectionFactory();
connection = connectionFactory.createConnection();
channel = connection.createChannel(false); /**
* 申明交换机 以及type
*/
channel.exchangeDeclare(RabbitConfig.EXCHANGE_ROUTE,"direct"); /**
* 发送消息
* 每个消费者 发送确认消息之前,消息队列不会发送下一个消息给消费者,一次只处理一个消息
* 自动模式无需设置下面设置
*/
int prefetchCount = 1;
channel.basicQos(prefetchCount); String Hello = ">>>> Hello EXCHANGE_ROUTE <<<<";
for (int i = 0; i < 5; i++) {
String message = Hello + i;
if (i == 3){
channel.basicPublish(RabbitConfig.EXCHANGE_ROUTE, RabbitConfig.ROUTINGKEY_A, null, message.getBytes());
}else{
channel.basicPublish(RabbitConfig.EXCHANGE_ROUTE, RabbitConfig.ROUTINGKEY_B, null, message.getBytes());
}
LOGGER.info("生产消息: " + message);
}
return "OK";
}catch (Exception e) { } finally {
connection.close();
channel.close();
return OK;
}
}
}
消费者1
package com.maozw.mq.routing; import com.maozw.mq.config.RabbitConfig;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory; import java.io.IOException; /**
* @author MAOZW
* @Description: ${todo}
* @date 2018/11/26 15:06
*/ public class RoutingConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(RoutingConsumer.class); public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = RabbitConfig.getConnectionFactory();
Connection connection = connectionFactory.createConnection();
Channel channel = connection.createChannel(false);
/**
* 创建队列申明
*/
boolean durable = true;
channel.queueDeclare(RabbitConfig.QUEUE_ROUTE, durable, false, false, null);
/**
* 绑定队列到交换机
*/
channel.queueBind(RabbitConfig.QUEUE_ROUTE, RabbitConfig.EXCHANGE_ROUTE,RabbitConfig.ROUTINGKEY_A); /**
* 改变分发规则
*/
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("[1] 接口数据 : " + new String(body, "utf-8"));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done!");
//消息应答:手动回执,手动确认消息
channel.basicAck(envelope.getDeliveryTag(),false);
}
}
};
//监听队列
/**
* autoAck 消息应答
* 默认轮询分发打开:true :这种模式一旦rabbitmq将消息发送给消费者,就会从内存中删除该消息,不关心客户端是否消费正常。
* 使用公平分发需要关闭autoAck:false 需要手动发送回执
*/
boolean autoAck = false;
channel.basicConsume(RabbitConfig.QUEUE_ROUTE,autoAck, consumer);
} }
package com.maozw.mq.routing; import com.maozw.mq.config.RabbitConfig;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory; import java.io.IOException; /**
* @author MAOZW
* @Description: ${todo}
* @date 2018/11/26 15:06
*/ public class RoutingConsumer2 {
private static final Logger LOGGER = LoggerFactory.getLogger(RoutingConsumer2.class); public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = RabbitConfig.getConnectionFactory();
Connection connection = connectionFactory.createConnection();
Channel channel = connection.createChannel(false);
/**
* 创建队列申明
*/
boolean durable = true;
channel.queueDeclare(RabbitConfig.QUEUE_ROUTE2, durable, false, false, null);
/**
* 绑定队列到交换机
*/
channel.queueBind(RabbitConfig.QUEUE_ROUTE2, RabbitConfig.EXCHANGE_ROUTE,RabbitConfig.ROUTINGKEY_B); /**
* 改变分发规则
*/
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("[2] 接口数据 : " + new String(body, "utf-8"));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done!");
//消息应答:手动回执,手动确认消息
channel.basicAck(envelope.getDeliveryTag(),false);
}
}
};
//监听队列
/**
* autoAck 消息应答
* 默认轮询分发打开:true :这种模式一旦rabbitmq将消息发送给消费者,就会从内存中删除该消息,不关心客户端是否消费正常。
* 使用公平分发需要关闭autoAck:false 需要手动发送回执
*/
boolean autoAck = false;
channel.basicConsume(RabbitConfig.QUEUE_ROUTE2,autoAck, consumer);
}
}
4.rabbitmq--路由模式的更多相关文章
- RabbitMQ路由模式
生产者 import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import utils.Connecti ...
- rabbitMQ的三种路由模式
rabbitMQ工作流程: 1.声明交换机 2.声明消息队列 3.绑定交换机和队列 4.生产者往交换机里发送新消息 5.交换机根据所选的模式和routingKey决定消息发往哪条消息队列 6.一个消费 ...
- RabbitMQ (六) 订阅者模式之路由模式 ( direct )
路由模式下,生产者发送消息时需要指定一个路由键(routingKey),交换机只会把消息转发给包含该路由键的队列 这里,我们改变一下声明交换机的方式. 我们通过管理后台添加一个交换机. 添加后,生产者 ...
- RabbitMQ六种队列模式-路由模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...
- RabbitMQ学习第四记:路由模式(direct)
1.什么是路由模式(direct) 路由模式是在使用交换机的同时,生产者指定路由发送数据,消费者绑定路由接受数据.与发布/订阅模式不同的是,发布/订阅模式只要是绑定了交换机的队列都会收到生产者向交换机 ...
- RabbitMQ 一二事(4) - 路由模式介绍
路由模式其实和订阅模式差不多,只不过交换机的类型不同而已 路由模式可以用下图来表示,比订阅模式多了一个key,举个栗子就是根据不同的人群来订阅公众号,来收取消息 根据不同的key来获取不同的消息 最简 ...
- python使用rabbitMQ介绍四(路由模式)
一.模式介绍 路由模式,与发布-订阅模式一样,消息发送到exchange中,消费者把队列绑定到exchange上. 这种模式在exchange上添加添加了一个路由键(routing-key),生产者发 ...
- RabbitMQ路由类型
关于RabbitMQ的Exchange类型 参考地址:<RabbitMQ学习系列(四): 几种Exchange 模式> github地址:https://github.com/ChenWe ...
- 1.RabbitMq - Work 模式
RabbitMq - Work 模式 一.什么是Work模式 如果有几个消息都需要处理,且每个消息的处理时间很长,仅有一个消费者,那么当它在处理一个消息的时候,其他消息就只有等待. 等待有时候是好的, ...
- RabbitMQ工作模式
------------恢复内容开始------------ RabbitMQ基本概念: Producer:生产者(消息的提供者) Consumer:消费者(消息的使用者) Message:消息(程序 ...
随机推荐
- redis常用api
一.全局命令 1.keys * //查看所有键 2.dbsize //键总数,如果存在大量键,线上禁止使用此命令 3.exists key //存在返 ...
- 13 Msql之四种事务隔离界别
一.事务的基本要素 1.原子性:事务开始后的所有操作,要么全部做完,要么全部不做,不能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没发生一样.也就是说事务是一个不可分割 ...
- android提升
https://blog.csdn.net/lou_liang/article/details/82856531
- scrapy 增量采集
在做新闻或者其它文章采集到时候,只想采集最新发布的信息,之前采集过得就不要再采集了,从而达到增量采集到需求 scrapy-deltafetch,是一个用于解决爬虫去重问题的第三方插件. scrapy- ...
- 《浏览器工作原理与实践》<02>TCP协议:如何保证页面文件能被完整送达浏览器?
前言: 在衡量 Web 页面性能的时候有一个重要的指标叫“FP(First Paint)”,是指从页面加载到首次开始绘制的时长.这个指标直接影响了用户的跳出率,更快的页面响应意味着更多的 PV.更高的 ...
- PHPStorm 3.3 破解方法 以及汉化
第一步修改host文件(host文件地址为): C:\Windows\System32\drivers\etc 将以下内容添加到host文件里面 0.0.0.0 account.jetbrai ...
- bat 判断变量字符串中是否包含字符串
bat 判断变量字符串中是否包含字符串 @echo off rem way 1 set str=machine-order-service set matchStr=orderd echo %str% ...
- SpringMVC问题整理
JSP页面无法获取ModelAndView里的值 自己搭的项目突然EL表达式取不到值了 不管是用 ${msg} 还是用JSTL的<c:out value="${msg}"/& ...
- IIS配置web.config 将带www域名转为不带www域名
在configuration节点中添加 <configuration> <system.webServer> <rewrite> <rules> < ...
- 数据结构系列文章之队列 FIFO
转载自https://mp.weixin.qq.com/s/ILgdI7JUBsiATFICyyDQ9w Osprey 鱼鹰谈单片机 3月2日 预计阅读时间: 6 分钟 这里的 FIFO 是先入先出 ...