RabbiMQ 原理及应用

  • AMQP协议

1.协议模型

 

1.协议连接步骤

1.1.生产者与服务建立连接----》连接host ----》exchange

1.2.Connection :建立连接

1.3.Channel:网络信道,是进行消息的读写的通道,客户端可建立多个channel,每个channel代表一个任务。

1.4.Message:由properties 和body组成。Properties可以对消息进行设置:是否延迟,发送时 机

1.5.Virtual host: 虚拟地址。进行逻辑隔离,是最上层的消息路由,比如说mq服务可能要关联多个业务服务,每个业务服务会需要对应一个独立的区域。一个virtual host 可以有多个exchange和queue。但同一个virtual host里面的exchange和queue的名称不能相同。

1.6.Exchange:路由。生产者把消息发送到路由器上

1.7.Bingding:exchange和Queue之间的虚拟连接,bingding可以包含routing key。

    1. Routing key:路由规则,虚拟机用其确认如何路由一个指定的消息,
    2. Queue:消息队列。

 

2. 交换机exchange

2.1 架构图

 

2.2.基本属性

 2.2.1.type: direct   , topic , fanout , headers ,( sharding  需要安装插件 )

 

2.2.2.Durability:是否需要持久化,true为需要

2.2.3.Auto Delete :

当最后一个绑定到Ecchange上的队列删除后,自动删除该exchange,即没有队列关联路由了

2.2.4.Internal:

当前exchange 是否用于MQ内部使用,默认为false。

Argurments

 

 2.3 Direct 路由

   即:所有发送到Direct Echange的消息被转发到RouteKey中指定的Queue

Direct模式可以使用RabbiMq自带的Exchange:default Exchange ,所以不需要将Exchange 进行任何绑定操作,消息传递时RouteKey 必须完全匹配才会被队列接收,否则消息被抛弃。

 

2.4. Topic

即:所有发送到Topic exchange的消息被转发到所有关系RouteKey中指定TopicQueue

ExchangeRouteKey和某个Topic进行模糊匹配

此时队列需要绑定一个topic

 

三.消息投递及确认

3.1 消息投递的保证

3.1.1. 生产端的可靠性投递

 

解析:生产端要把要发送的消息持久化而不是直接发送。

Bconfirm Listener :接收消费端的消息是否被消费成功。True就是成功了

   如果step3 由于网络抖动,消费端没有把成功消费的消息告知生产者。

CRetry send :生产端可以设置一个消息超时时间,如果超时后会重新发送

 

即保证消息成功发出,且发送端收到MQ接口broker确认应答

还有消息的补偿机制

C.收到消息的持久化

D.消息的延迟投递,做二次确认,回调检查

3.1.2 可靠性投递三

在高并发场景下的消息投递

即消息的延迟投递,做二次确认,回调检查

主要是减少数据库操作,

 

解析:stop1:生产消息

Step2 :若干时间后订阅消息被消费的确认通知,该通知由回调服务发送

Step4:如果消息被正常消息则向mq发送消息服务通知回调服务

Step5:监听消息被正常消费后持久化数据

Step6:如果消息消费失败,则发起补偿通知给消息的生产者

  1. Upstream service: 生产端,上游服务

第一步把发送的消息先入库

DownStream service :消费端

CCallBack service :回调服务

DMQ Broker

 

备注:在整个业务链条中没有任何分布式事务

3.1.3 . 消息的幂等性

3.1.3.1. 消费端保证消息的幂等性

即数据库的乐观锁

A.在海量订单的业务高峰期,如何避免消息重复消费?

即:消费端实现消息的幂等性

 

  1. 主流方案:(1)唯一ID+指纹码机制,利用数据库主键去重

Select count( 1 ) from table where id = 唯一ID+指纹码机制(业务规则)

好处:实现简单

缺点:高并发下对数据库的写入的性能瓶颈

解决方案:ID进行分库分表进行算法路由。

2)利用redis原子性去重

 

 

 

 

 

 

 

 

 

 

3.2 消息的ACK和重回队列

可靠性投递

 

3.2.1 确认机制实现

 A.第一步,在channel上开启确认模式:channelconfirmSelect();

B. 第二步,在channel上添加监听,addConfirmListener,监听成功和识别的返回结果,根据具体的结果对消息进行重新发送或记录日志后续处理

 

3.2.2 return 消息机制

Areturn Listener 用于处理一些不可路由消息:即发送的消息当前的exchange不存在或者路由的key路由不到。这个时候就要监听这种不可达的消息,使用Return Listener

 

3.2.3.生产者发送消息后怎么样确认mq服务器是否收到消息

两各方式:

  1. AmQP 实现了事务机制

 

事务机制

  1. Txselect

用户将当期channel设置成transation模式,trCommit用于提交事务,如果有异常则txRollback回滚

 

 

  1. 消息可靠性投递confirm 模式

生产者端confirm模式的实现原理:

3.3 消息限流

3.3.1 消费端的限流

 EgRabbitMq 服务器有数万条消息,当

RabbitMq提供了一种qos(服务质量保证)功能,

 

3.3 消费端ACK与重回队列

3.3.1 手工ACK和NACK

A.消费端未消费成功,程序本身的异常,业务异常,可以进行消息补偿

B.演技

 

3.3.2. 消费端的重回队列

A.对于没有成功消费的消息重新给broker

 

3.3.3. API 使用说明

 

 

 

 

3.4 TTL消息

解释:RabbitMq 支持消息的过期时间,当消息发送时可以指定消息生存时间

         RabbitMq也支持队列的过期时间,从消息的入队列开始计算,只要超过了队列的超时时间,则消息会自动清除。

 

 

 

3.4.1

 

3.5 死信队列—DLX

3.5.1 当消息在队列中变成死信,

 

3.5.2 消息变成死信的途径

A.消息被拒绝 request=false

B.消息TTL过期

C.队列长度最大

 

 

四.RabbitMq 使用

 

  1. 使用方式种类:
    1. 单发送多接受
    2. 发布订阅模式

 

 

 

2. 怎样保证消息的稳定性

2.1. publisher confirms :发布方确认

2.2. message 持久化

 

2.3 acknowlegement :Consumer 确认

 

3.怎样避免消息丢失

3.1  将Queue 和message 都设置为可持久化,还有就是使用事务,

 

  1. RabbitMq 持久化的特点
    1. 如果要在重启后保持消息的持久化必须设置消息是持久化的标识

 

4.消息的广播类型

4.1.fanout广播模式

 

4.2.direct 广播模式

 

4.3 topic 广播模式

 

5. 怎样实现延迟消息队列??

5.1 延迟任务通过消息的TTL 和 Dead letter exchange来实现。

我们需要建立2个队列,一个用于发送消息,一个用于消息过期后的转发目标队列

 

 

6.RabbitMq 集群作用

6.1 集群里面可以共享user,vhost ,queue,exchange ,

所有的数据和状态都是必须在所有节点上覆制的。一个例外是

 

7.rabbitMq的节点类型

7.1 内存节点

7.2 磁盘节点

 

五.RabbitMq 集群架构

1. 主备架构模式

主节点可以提供读写,但从节点不做任何事情,只在主节点宕机时,从节点替代主节点服务。这个主从的模式是有本质区别的。这个架构在并发量低的业务可以使用

这个模式activemq 利用zk 做主备一样。

1.1 主备架构设计

 

  1. Haproxy:是一个tcp基别的代理,

其配置如下:

Bind 0.0.0.0:5672 #配置tcp模式

Mode tcp #简单的轮询

Balance roundrobin #主节点

Server bhz76 IP :5672 check inter 5000 rise 2 fall 2

Server bhz77 IP:5672 backup check inter 5000 rise 2 fall 2 #备用节点

说明:集群节点配置#inter每个5秒对mq集群做健康检查,2次正确证明服务器可用,3次失败证明服务器不可用

 

 

 

2.远程模式架构

2.1 说明:远程模式可以实现双活的一种模式,简称shovel模式,

即把消息进行不同数据中心的复制,可以跨地域让多个mq集群互联

 

3.镜像模式架构Mirror

3.1 Mirror镜像队列,

为了保证rabbitm数据的高可用解决方案,主要是实现数据的同步,一般是

3个节点,该模式可保证数据完全不丢失。

3.2.架构图

 

      1.  keepAlived:

 

 

4.多活模式

4.1 是实现异地数据复制的主流模式,

因为shovel模式配置复杂。这个模式依赖插件:federation插件,可实现AMQP的数据通信

4.2. 架构图

 

Federation exchange:不需要构建cluster,在brokers之间传输消息。连接的双方可使用不同的users和virtual hosts 。双方也可以

 

 

六.镜像集群搭建

 

 

1.服务组件

2.keepAlived

主要是通过VRRP(虚拟路由器冗余协议)协议实现高可用功能,

  1. 三个作用:
  1. 管理LVS软件
  2. 实现LVS集群的监控检测

 

 

  1. 集群配置
    1. hipe_compile: erlang compiler编译小提示性能
    2. vm_memory_high_watermark:内存低水位线,若地域该水位线,则

 

 

 

 

七.RabbitMq 设计架构整体方案

1.实现思路

 

 

2.架构完成功能:

  1. 支持消息高序列化的转化和异步发送
  2. 支持消费和生产的实例的连接池化缓存化,
  3. 支持可靠性投递,保障消息不能丢失
  4. 支持消费端的幂等性操作,避免消费端重复消费
  5. 支持快速消息发送,在日志收集,统计分析等需求下保证高吞吐量
  6. 支持延迟消息模式,消息可以延迟发送,指定延迟时间,用于延迟检查,服务限流场景
  7. 支持事务消息,保障100%可靠性投递,
  8. 支持顺序消息,保障消息送达消费端的前后顺序,例如下订单等复合操作
  9. 支持消息补偿,重试,快速定位异常,失败消息
  10. 支持消息集群负载均衡,保障消息落到具体set集群
  11. 支持消息路由策略

 

3.生产端组件说明

3.1.RabbitTemplateContainer : RabbitTemplate复用池,高并发下可以重复利用

    1. RabbitTemplateConfirmCallback

 

 

4. 消费端组件

4.1.AsycnMessageInter:

4.2. IdempotenRabbitHandler:消费者幂等性保障拦截器

    1.  

 

 

 

5.架构模式说明

5.1迅速发送消息模式

 

 

6. 事务消息

Eg:单笔大额现金交易,希望这个消息优先级最高,且可靠性要求100%。和银行系统都要兼顾,所以要有补偿机制,主动发起银行查询指令机制。

 

 

 

 

6.1. txSelect 和confirmSelect 机制

 支持事务,传统的RabbitMq自身的事务和spring机制在高并发下会消耗系统资源出现阻塞

。因此采用可靠性投递机制,就是补偿机制。数据源使用一个,也就是业务操作的DB2和消息记录操作DB1使用的是一个数据库源。可以用一个数据库实例,但是两个数据库

最后利用spring DataSourceTransactionManager 在本地进行发送消息,当消息发送失败时可进行补偿。

 

 

6.2.消息的幂等性

6.2.1. 非幂等性:

A.可靠性消息投递机制

B. MQ broker 服务于消费端传输消息的过程中的网络抖动

 

 

 

3.3.2.幂等性设计架构

 

 

说明:

  1. 需要有全局唯一id
  2. ID路由组件:将信息入库,因为单点压力过大

  当然也可以通过redis做持久化

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章