消息中间件-RabbitMQ

RabbitMq

  为什么要写RabbitMQ,首先消息中间件在现在的web开发中担当着非常重要的角色,特别是微服务的流行,在处理各个服务间数据异步交互非常有效。
当时接触的第一个消息中间件也是RabbitMQ。写这篇文字一是对之前的知识做一个总结,由于能力有限,没法从源码到实现细节做较多的分析,主要也是
作为一种知识笔记,在后面可以直接通过该文章作为认知参考。以下内容会根据对RabbitMQ的不断认识与应用不断总结。

  服务端使用版本号:3.7.8。



介绍

RabbitMQ是轻量级的,易于部署在本地或云环境中。 它支持多种消息传递协议。 RabbitMQ可以部署在分布式和联邦配置中,以满足大规模、高可用性的需求
都说rabbitmq基于erlang语言实现,先天有处理的高并发的优势

支持的语言非常丰富:
JAVA
.NET
Ruby
Python
PHP
Javascript
Go
Rust
...

支持多种协议:
AMQP
STOMP
MQTT
HTTP
WebSocket
...

特色

  • Asynchronous Messaging :支持多种协议的异步消息
  • Developer Experience : 支持多语言
  • Distributed Deployment :支持分布式部署
  • Enterprise & Cloud Ready :可插拔的认证授权机制,轻量级云部署
  • Tools & Plugins : 多种工具和插件支持企业持续集成
  • Management & Monitoring :http、命令管理以及UI界面实现管理和监控

名词

名称 描述
broker 中间件
connection 连接:与rabbitMq通信必须先建立连接,rabbit基于amqp协议,顶层仍是通过tcp进行数据传输
channel 通道:一个连接可以有多个通道,实现连接复用,减少多个连接对资源的浪费
vhost 虚拟主机:实现了数据在逻辑上的隔离
exchange 交换机:消息都是先交换机,根据交换机与队列的bindingKey实现消息的分发
queue 队列:消息的载体
  • exchange声明参数

name: 交换机名称
type: fanout|direct|topic|headers
durable: 是否持久性
autoDelete: 是否自动删除
internal: 是否内部交换机。如果true,则不能通过客户端直接使用,只能通过交换路由(channel.exchangebind)的形式使用
arguments: 交换机参数

  • 参数名 参数说明
    alternate-exchange 配置备用交换机,当发送到交换机的消息路由到任何队列时,则会将消息发布到指定的备用交换机上
  • queue声明参数

durable 持久性?是否在服务器重启后保留该队列
exclusive 独占队列?是否在一个连接内被锁定,注意是在一个连接而不是一个通道上。包含autoDelete特性
autoDelete 自动删除?不再使用是自动删除,生产与消费端都断开了连接
arguments 参数?\

  • 参数名 参数说明
    x-message-ttl 队列内消息存活时间(TTL),如果超过该时间,且配置DLX则消息会发送到死信队列中,否则丢弃
    x-expires 队列存活时间
    x-max-length 队列中消息最大数量,超过时删除之前的消息
    x-max-length-bytes 队列中消息占用内存大小,超过时删除之前的消息
    x-dead-letter-exchange 死信交换机名称(DLX)
    x-dead-letter-routing-key 死信routingKey
    x-max-priority 队列支持的最大优先级,1 到 255 之间的正整数
    x-queue-mode lazy,尽可能早地将消息移动到磁盘,消息在消费时才会被加载到内存中
    x-queue-master-locator min-masters/client-local/random,集群时让队列领导可以使用多种策略分布在节点之间
  • 消息发布参数

mandatory: 为true时,当交换机没有匹配到路由时,消息被return;否则消息丢弃
immediate: 为true时,如果队列有关联消费者则消费,否则消息被return;否则消息不处理 ?
properties: 消息属性

  • 参数名 参数说明
    contentType 消息类型
    contentEncoding 消息编码
    headers 消息头,headers模式可以用到
    deliveryMode 传输模式,写入内存或磁盘
    priority 优先级,x-max-priority相关
    correlationId 关联id
    replyTo rpc时用到
    expiration 过期时间
    messageId 消息id
    timestamp
    type
    userId
    appId
    clusterId 集群id

应用场景

应用解耦
异步业务
流量削峰
RPC
延迟业务
负载均衡

EXCHANGE

  • fanout
    广播,将消息发送到所有与交换机绑定的队列上

  • direct
    将消息发送到与交换机routingKey匹配的队列上
    与fanout的区别,如果有多个消费者,fanout交换机会把消息发送到每一个消费者上,而direct不会

  • topic
    将消息发送到与交换机routingKey匹配的队列上,基于routingKey和bindingKey,支持通配符匹配

  • headers
    基于消息properties进行批量

示例情形

simple

简单地实现消息生产与消费

work-queues

多个消费者订阅一个消息队列,完成消息均匀消费的目的,实现消息的分发

publish-subscribe

基于fanout交换机,实现将消息完整地发布到与之绑定的所有队列上,实现发布订阅模式

routing

基于direct交换机,根据消息发布key与队列绑定key相同,按业务类型实现消息的定向分发

topcis

基于topic交换机,根据消息发布key与队列绑定key的匹配规则,按业务类型实现消息的定向分发

rpc

基于消息队列的RPC

消息生产

  • 可靠性

    • 如何确保消息发送成功?

      • 消息发送到exchange
      • 消息发送到queue
    • rabbitmq如何实现?

      • 事务机制 (TX)
      • 发送确认机制 (ACK)
  • 重试策略

    • 消息没有发送到中间件

      • 可基于类似于spring-retry这样的框架,重复发送
    • 消息发送到中间件失败

      • 基于消息发送回调
      • 基于定时重试策略
  • 死信

    • 条件
      • 消息被拒绝(Basic.Reject/Basic.Nack) ,井且设置requeue 参数为false
      • 消息过期
      • 队列达到最大长度

消息消费

  • 重复消费
    • 主要是在业务上的重复

      • 不同业务
      • 同一业务不同状态,由于消息消费顺序导致后发送的消息先被消费
    • 中间件层面的重复

      • 因为网络或其他原因导致消息的重复发送或重传消费

问题

  • 消息的有序性

    消息的优先级,只能在一定 程度上实现消息消费顺序,无法保证消息的逻辑上的顺序

  • 消息积压

    消息的生产与消费不均衡

注意事项

1、根据路由规则,消息会全部发送到匹配的队列上,但是同一个队列上多个消费者会不重复消费所有消息
2、autoDelete并不是简单的队列没有生产或订阅就会被删除,比如生产者往队列里生产消息,但是该队列至始至终都没有过消费者订阅,那么就算生产者断开了,
队列一样不会自动删除

参考文档

posted @ 2022-03-13 16:32  Cycads  阅读(122)  评论(0)    收藏  举报