一、mq简介
mq 的特点:
- 屏蔽异构平台的细节:发送方、接收方系统之间不需要了解双方,只需认识消息。
- 异步:消息堆积能力;发送方接收方不需同时在线,发送方接收方不需同时扩容(削峰)。
- 解耦:防止引入过多的API给系统的稳定性带来风险;调用方使用不当会给被调用方系统造成压力,被调用方处理不当会降低调用方系统的响应能力。
- 复用:一次发送多次消费。
- 可靠:一次保证消息的传递。如果发送消息时接收者不可用,消息队列会保留消息,直到成功地传递它。
- 提供路由:发送者无需与接收者建立连接,双方通过消息队列保证消息能够从发送者路由到接收者,甚至对于本来网络不易互通的两个服务,也可以提供消息路由。
核心优势:
- 优点:解耦、异步、削峰
- 缺点:一致性问题:消息传递给多个系统,部分执行成功,部分执行失败,容易导致数据不一致
mq 常用参数解释
参数 | 解释 | 特殊备注 |
---|---|---|
Broker | 它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进行传输 | |
Exchange | 消息交换机,它指定消息按什么规则,路由到哪个队列 | |
queue | 队列名称 | |
Binding | 绑定,它的作用就是把exchange和queue按照路由规则绑定起来 | |
Routing Key | 路由关键字,exchange根据这个关键字进行消息投递 | |
Producer | 消息生产者,就是投递消息的程序. | |
Consumer | 消息消费者,就是接受消息的程序 | |
Channel | 消息通道,在客户端的每个连接里,可建立多个channel | |
durable | 是否持久化, 队列的声明默认是存放到内存中的,如果rabbitmq重启会丢失,如果想重启之后还存在就要使队列持久化,保存到Erlang自带的Mnesia数据库中,当rabbitmq重启之后会读取该数据库 | |
autoDelete | 是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除,可以通过RabbitMQ Management,查看某个队列的消费者数量,当consumers = 0时队列就会自动删除 |
Message acknowledgment消息确认
- 为了保证数据不被丢失,RabbitMQ支持消息确认机制,为了保证数据能被正确处理而不仅仅是被Consumer收到,那么我们不能采用no-ack,而应该是在处理完数据之后发送ack.
url = app.config['KOMBU_CONNECTIONS']['default']
job = ShouTuMasterRewardJob.create_from_url(url)
# no_ack=False 表示 需要消息确认机制
# ack_anyway=True 表示 需要消息确认机制的时候,程序无需应答,自动应答
job.configure(queue=QUEUE, no_ack=False, ack_anyway=True)
job.main()
# ack 模式需要在代码中确认
self.process_ok # 确认ok
# ps: 如果程序中忘记 设置,会导致消息积压,到内存限制爆掉
批量处理消息
- prefetch: 消费者单次取多少条消息
- global_prefetch:由于消费者自身处理能力有限,从rabbitmq获取一定数量的消息后,希望rabbitmq不再将队列中的消息推送过来,当对消息处理完后(即对消息进行了ack,并且有能力处理更多的消息)再接收来自队列的消息
# 设置每个consumer一次最多处理prefetch个消息,所有consumer总共处理global_prefetch个消息
job.configure(queue=QUEUE, no_ack=False, prefetch=5, global_prefetch=20)
下线mq
- 停止生成者
- 停止消费者
- 如果未设置 autoDelete,需要手动删除