1.Server
也叫broker,接受客户端的连接,实现amqp实现实体服务
2.Connection
Connection连接,应用程序与Broker(server)的网络连接
3.Channel
Channel,网络信道,几乎所有的操作的都在channel中进行,channel是进行消息的读写通道,客户端客建立多个channel,每个channel代表一个会话任务。
4.Message
消息实体,服务器和应用程序之间的传送数据,有Properties和body组成,properties可以对消息进行修饰,比如消息的优先级,延迟等高级特性,body则就是消息体的内容。
5.VirtualHost
VirtualHost:虚拟主机,进行用于逻辑隔离,最上层的消息路由,一个virtualhost里面可以有若干个Exchange和Queue,同一个VirtualHost里面不能有相同的名称Exchange和Queue.主要用于更外层的路由,在virtualHost的分区作用,划分更抽象层次的时候的路由划分
6.Exchange(exchange route and filter message)
交换机,接收消息,根据路由转发到绑定队列,路由key和路由queue队列的绑定关系列表,主要就存放到exchange,进行绑定key,可以绑定多个message key queue
7.Queue(store the message data)
消息队列服务机制,主要用于控制消息队列数据信息的存放仓库队列
Exchange交换机:
交换机:exchange,接收消息,并根据路由键转发消息锁绑定的队列。建立一个routekey绑定到queue的关系拓扑图,之后交换机自主意识将对应routekey的值,返回到相关的队列中去,也可以作为一个缓存区,用户之后可以从queue中获取消息数据
属性
-
Name:交换机名称
-
Type:direct\topic\fanout\headers (sharding)
-
Durability:是否持久化,true持计划
-
AutoDelete:当交换机中绑定的队列都删除了,则交换机会自动删除
-
Internal:当前交换机是否用于RabbmitMQ内部使用,默认为False
-
Arguments:扩展参数,用于扩展AMQP自定制化协议使用
Direct Exchange
-
所有发送到Direct Exchange的消息都会被转发到RouteKey指定的Queue
-
Direct 模式 使用RabbitMQ自带的Exchange:default Exchange,所以不需将Exchange进行任何绑定(binding)操作,消息传递是,routekey必须完全匹配才会被队列接收,否则会被丢弃。
Topic Exchange
所发送到Topic Exchange 的消息被转发到所有关心RouteKey中指定的Topic的queue上,Exhchange将Routekey和某个topic进行模糊匹配,队列需要绑定一个topic
主要符号:
-
代表匹配一个或者多个词
-
*代表匹配一个不多或者不少一个词
-
Fanout Exchange(性能最好)不匹配任何规则,不处理路由键,只需要简单的将队列绑定到交换机上。
发送到交换机的消息队徽被转发到该交换机绑定的所有队列上
1.消息如何保证百分之百投递成功
1.1 保证消息的成功发出
1.2 保证MQ节点的成果接收
1.3 发送端受到MQ节点(broker)确认应答
1.4 消息的补偿机制实现
-
(不适合高并发)消息落库,消息状态进行打标,发送中->发送结束(消息确认)->修改状态(已发送)
分布式任务进行分布式扫描抓取MQDB数据库的信息记录状态,根据状态进行发送消息信息。
重试超时次数,设置超过阈值之后,无法进行再次重试,放弃重试机制。
-
(适合高并发)消息延迟投递,做二次确认,回调检查。
先将持久化数据库落库数据,之后发送消息,之后再发一次延迟消息检查。
消费端获取到了消息数据,进行confirm确认标识机制(消费端发一次消息给MQ)
callback服务监控confirm消息信息,做数据库存储持久化
callback服务监控second check ,然后去检查之前是否存在此条数据库,如果没有,则说明失败
因此就会rpc通知消息中心,再次发送首次发送消息的功能
2.幂等性概念详解
2.1 幂等性:我们可以借鉴数据库的乐观锁机制:
(1)比如我们只想一条更新库存的sql语句
update 条件的时候,可以考虑待这个这个version操作(加版本号控制,进行乐观锁控制快速失败)
唯一ID+指纹码 机制 利用数据库主键去重
select count(1) from T_ORDER WHERE ID = 唯一ID+指纹码
好处:简单
坏处:并发下有数据库写入的性能瓶颈
解决方案:跟进ID进行分库分表进行算法路由(多库多表机制)
(2)利用Redis的原子性实现
使用Redis实现幂等性操作,需要考虑 问题
第一 我们是否进行数据库落库,如果落库,关键解决的问题就是如何做到数据库的缓存的原子性
第二 如果不进行落库,那么都存储到缓存,如何设置同步策略。
3.海量订单产生的业务高峰期,如何避免消息的重复消费?
同上!
4.confirm消息确认机制
消息的确认,生产者投递消息之后,如果broker受到消息,则会给我们生产者一个应答。
生产者进行接收应答,用来确定这条消息是否正常的发生到broker,这中方式也是消息可靠性的投递核心保障。
channel模式添加确认模式:channel.confirmSelect()
channel上面添加addConfirmListener,监听成功或者失败的返回结果,根据亏具体的结果对消息进行重新发生,或者日志记录等后续处理。