乐趣区

关于后端:与RabbitMQ有关的一些知识

工作中用过一段时间的 Kafka,不过次要还是 RabbitMQ 用的多一些。明天次要来讲讲与 RabbitMQ 相干的一些常识。一些基本概念,以及理论应用场景及一些注意事项。

1 基本概念

RabbitMQ 应用 Erlang 开发,实现了高级音讯队列协定(AMQP),同时还反对 MQTT、STOMP 等。

1.1 外围概念

  • Broker: 音讯队列服务主机
  • Exchange: 音讯交换机,可依照特定规定将音讯路由到具体队列 (上图 X 即为交换机)
  • Queue: 音讯队列,每个音讯实践都要被投入到一个或多个队列 (上图红色矩形即为队列)
  • Binding: 绑定关系,将 ExchangeQueue依照某个路由规定进行绑定
  • RoutingKey: 路由关键字,Exchange依据该 Key 进行不同的路由
  • Vhost: 虚拟主机,在同一物理主机上做资源逻辑隔离,相似 命名空间?
  • Connection: 客户端与主机建设的 TCP 连贯
  • Channel: 音讯通道,同一 Connection 能够有多个 Channel,每个Channel 都有一个惟一 ID

1.2 交换机

按类型分四种:Direct Exchange,Topic Exchage,Fanout Exchange,Headers Exchange

1.2.1 Direct Exchange

间接交换机,在没简单路由场景时,这种路由器应用的较多。特点是 严格 RoutingKey路由。只有当 RoutingKey 完全一致时,才会明天路由投递。

1.2.2 Fanout Exchange

播送交换机,一个音讯须要无差别投递到所有绑定的队列中时。无需设置RoutingKey,即便设置了也不会失效。

1.2.3 Topic Exchange

主题交换机,相似间接交换机。不同的是能够依据 RoutingKey 进行含糊匹配 (# 示意一个或多个单词,*示意一个单词)。

这样来看的话。

  • 当不应用 #*进行含糊匹配时,它跟 Direct Exchange 仿佛没啥区别。
  • 当仅应用 # 进行含糊匹配时,它跟 Fanout Exchange 仿佛也没啥区别。

能够看到:

  • Q1能够匹配:x11.orange.x22,但无奈匹配x00.x11.orange.x22
  • Q2能够匹配:lazy.orange,也能匹配lazy.orange.rabbit
1.2.4 Headers Exchange

申请头交换机,不应用 RoutingKey 路由,依据音讯头中的 key-value 属性进行路由。

能够通过设置 x-match: anyx-match: all 来进行 orand 逻辑匹配。

1.2.5 其余属性
  • Durability: Durable(长久的),Transiant(短暂的)。
  • Auto delete:当有队列或交换机绑定了本交换机,在队列或者交换机都又进行理解绑后,主动删除
  • Internal: 是否为外部应用。true 示意为外部交换机,客户端无奈间接向该交换机发送音讯。
  • Arguments:

    • alternate-exchange: 备份交换机,当音讯无奈路由到具体队列时,将交给备份交换机解决。

1.3 队列

音讯只能存在于队列中,上面看一下队列都有哪些属性。

  • Type: Classic,Quorum
  • Durability: Durable(长久的),Transiant(短暂的)
  • Auto delete: 当有消费者订阅,而后所有的消费者又都断开连接,则主动删除
  • Arguments:

    • x-message-ttl: MessageQueue 中存活工夫,超时将被抛弃
    • x-expires: Queue在没有被应用的状况下,过期工夫
    • x-max-length: Queue中能够寄存的最大音讯数,超过将被抛弃
    • x-max-length-bytes: Queue中能够寄存最大音讯体大小,超过将被抛弃
    • x-overflow: Queue溢出后的行为,drop-headreject-publishreject-publish-dlx
    • x-single-active-consumer: 确保只有一个消费者订阅,当出现异常时主动转向另外一个。
    • x-max-priority: 队列反对的最大优先级,不设置将不反对。
    • x-dead-letter-exchange: 当 Messagerejectedexpire 时,将会被从新公布到哪个交换机。
    • x-dead-letter-routing-key: 当成为死信时,应用的RoutingKey,未设置时则应用原始Key
    • x-queue-mode: 当设置为 lazy 时,会将音讯尽可能的搁置到磁盘上,以缩小内存应用。
    • x-queue-master-locator: 将队列设置为主节点定位模式。

2 应用场景

利用场景个别为三类: 异步、解耦、削峰填谷。

2.1 异步

异步个别是指: 同一个零碎内,应用队列将申请和响应异步化,不阻塞主线程,从而取得更高的处理速度,以晋升零碎性能。

最早在做商城我的项目时。用户下单付款后先更新本地订单记录,而后再向第三方物流零碎推送待发货音讯、向用户发放订单相干站内信、并可能触发积分赠送及推荐人的返利计算、以及可能触发相干营销规定发放优惠券等操作。

2.2 解耦

解耦个别指: 不同零碎间,通过队列形式进行通信,使零碎间不至于适度依赖,缩小零碎间耦合性。

在最近的我的项目中,有做的一个事件上报零碎,其实就是各个系统都接入。每个零碎即可做生产者、也能够做消费者。比方用户在下单后,须要给推荐人赠送积分、向内部 CRM 同步商机已成单状态等。

2.3 削峰填谷

削峰填谷个别指: 利用队列作为缓冲,将短时大流量缓存起来,由消费者来决定处理速度。使得零碎负载趋于平稳,从而进步零碎稳定性。

在做用户增长业务相干,用户由落地页提交数据至外部零碎,外部零碎会将数据简略解决后推送到内部 CRM 零碎,销售在跟客户沟通后,会将线索转换为商机。在这个转换过程中,会由 CRM 向外部零碎推送数据。外部零碎会依据传递过去的数据进行各种操作,如创立、更新家长,创立、更新学生,以及各种附加业务信息等。

3 常见问题

3.1 音讯反复问题

音讯反复的场景很多,比方零碎出错、调用超时重试机制、音讯生产异样时 ReQueue 操作等状况。很多时候为了保障音讯的牢靠传递,会保障音讯at-least-once。这种状况下根本无奈保障不反复发送,所以生产端要保障幂等性。

既然提到重复性,必然要有反复的根据。比方订单号,同一零碎内不容许反复。

  • 可借助数据库的 惟一索引,也可借助 Redis 来保证数据惟一。
  • 如果没有反复根据,只能大略依据参数值按肯定规定做哈希解决,不过这种可能存在误判和漏判问题。

3.2 音讯沉积

生产沉积,无非就是生产速度赶不上生产速度。产生的起因有很多,消费者异样呈现生产变慢问题、生产者突发大流量等状况。

解决方案要同时思考生产者和消费者。产生沉积时,将局部生产者降级,敞开非核心业务,缩小音讯产生。消费者优化性能,将沉积音讯长期转移至新队列,启用新的消费者去生产。

3.3 音讯失落问题

从整个流程思考,生产者、队列、消费者三方面。

  • 生产者: 保障音讯胜利推送到队列。
  • 队列: 保障已推送到队列中的数据不会失落。
  • 消费者: 保障已生产的数据被正确处理。

4 后记

零碎设计没有银弹。在引入一个中间件时,要综合思考、权衡利弊。引入中间件,能解决一些问题,但可能会带来更多的问题。

做好系统监控,像生产沉积有些场景下是可预知的,比方长期做流动或者高价促销之类造成的订单激增。而有些像系统故障类,无奈提前预知,则须要监控零碎做到及时告警,提前染指解决。


echo '5Y6f5Yib5paH56ugOiDmjpjph5Eo5L2g5oCO5LmI5Zad5aW26Iy25ZWKWzkyMzI0NTQ5NzU1NTA4MF0pL+aAneWQpihscGUyMzQp' | base64 -d
退出移动版