文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一.其他知识点
1.1 幂等性
用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误立即回滚,但是再响应客户端的时候也有可能出现网络中断或者异常等等 .
消费者在消费 MQ中的消息时,MQ已把消息发送给消费者,消费者在给 MQ返回 ack时网络中断,故 MQ未收到确认信息,该条消息会重新发给其他的消费者,或者在网络重连后再次发送给该消费者,但实际上该消费者已成功消费了该条消息,造成消费者消费了重复的消息。
解决思路: MQ消费者的幂等性的解决一般使用全局 ID 或者写个唯一标识比如时间戳 或者 UUID 或者订单消费者消费 MQ中的消息也可利用 MQ的该 id来判断,或者可按自己的规则生成一个全局唯一 id,每次消费消息时用该 id先判断该消息是否已消费过。
消费端的幂等性保障: 在海量订单生成的业务高峰期,生产端有可能就会重复发生了消息,这时候消费端就要实现幂等性,这就意味着我们的消息永远不会被消费多次,即使我们收到了一样的消息。业界主流的幂等性有两种操作:
a.唯一 ID+指纹码机制,利用数据库主键去重
b.利用 redis的原子性去实现
唯一 ID+指纹码机制: 指纹码:我们的一些规则或者时间戳加别的服务给到的唯一信息码,它并不一定是我们系统生成的,基本都是由我们的业务规则拼接而来,但是一定要保证唯一性,然后就利用查询语句进行判断这个 id是否存在数据库中,优势就是实现简单就一个拼接,然后查询判断是否重复;劣势就是在高并发时,如果是单个数据库就会有写入性能瓶颈当然也可以采用分库分表提升性能,但也不是我们最推荐的方式。
Redis原子性:利用 redis执行 setnx命令,天然具有幂等性。从而实现不重复消费
-------------------以上均引自尚硅谷
1.2 优先级队列
场景: 向用户发送短信提醒,根据用户订单规模优先推送.
优先级范围:0-255;越大优先级越高(业界一般允许0-10)
队列中添加优先级范围
Map<String, Object> params = new HashMap();
params.put("x-max-priority", 10); // 设置优先级范围0-10
channel.queueDeclare("hello", true, false, false, params);
消息中添加优先级
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();
注意要让生产者批量发消息给MQ,这才有机会去排序.
1.3 惰性队列
场景:
default和 lazy。默认的为 default模式,在 3.6.0之前的版本无需做任何变更。lazy模式即为惰性队列的模式,可以通过调用 channel.queueDeclare方法的时候在参数中设置,也可以通过Policy的方式设置,如果一个队列同时使用这两种方式设置的话,那么 Policy的方式具备更高的优先级。
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-queue-mode", "lazy");
channel.queueDeclare("myqueue", false, false, false, args);
二.镜像队列
为了解决:交换机不可复用问题.交换机宕机造成队列消失. 即便是进行过持久化操作,但仍无法避免由于缓存导致的问题:因为消息在发送之后和被写入磁盘井执行刷盘动作之间存在一个短暂却会产生问题的时间窗。
类似于redis主从集群,保证消息不丢失.
三.实现负载高可用
在java中写死了消息队列ip.当该ip挂掉我们就再也无法发送消息.这时需要nginx实现负载均衡.我们只需连接nginx,由nginx实现代理转发.
四.联邦交换机(Federation Exchange)
场景:保证跨地域消息队列数据一致性.降低延迟问题.
每台机器都要安装
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management
五.联邦队列(Federation Queue)
联邦队列可以在多个 Broker节点(或者集群)之间为单个队列提供均衡负载的功能。一个联邦队列可以连接一个或者多个上游队列(upstream queue),并从这些上游队列中获取消息以满足本地消费者消费消息的需求。
六.Shovel
Federation具备的数据转发功能类似,Shovel够可靠、持续地从一个 Broker中的队列(作为源端,即source)拉取数据并转发至另一个 Broker中的交换器(作为目的端,即 destination)。作为源端的队列和作为目的端的交换器可以同时位于同一个 Broker,也可以位于不同的 Broker上。
docker安装rabbitMQ插件过程
每台机器安装
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management