什么是消息中间件
消息指的是两个应用间传递的数据。数据的类型有很多种形式,可能只包含文本字符串,也可能包含嵌入对象。
消息队列(Message Queue) 是在消息的传输过程中保存消息的容器。在消息队列中,通常有生产者和消费者两个角色。生产者只负责发送数据到消息队列,并不会取在乎谁从消息队列中取出数据处理。消费者只负责从消息队列中取出数据处理,并不在乎这是谁发送的数据。
消息队列的作用
- 解耦如图所示。假设有系统B、C、D都需要系统A的数据,于是系统A调用三个方法发送数据到B、C、D。这时,系统D不需要了,那就需要在系统A把相关的代码删掉。假设这时有个新的系统E需要数据,这时系统A又要增加调用系统E的代码。为了降低这种强耦合,就可以使用MQ,系统A只需要把数据发送到MQ,其他系统如果需要数据,则从MQ中获取即可。
- 异步如图所示。一个客户端请求发送进来,系统A会调用系统B、C、D三个系统,同步请求的话,响应时间就是系统A、B、C、D的总和,也就是800ms。如果使用MQ,系统A发送数据到MQ,然后就可以返回响应给客户端,不需要再等待系统B、C、D的响应,可以大大地提高性能。对于一些非必要的业务,比如发送短信,发送邮件等等,就可以采用MQ。
- 削峰。这其实是MQ一个很重要的应用。假设系统A在某一段时间请求数暴增,有5000个请求发送过来,系统A这时就会发送5000条SQL进入MySQL进行执行,MySQL对于如此庞大的请求当然处理不过来,MySQL就会崩溃,导致系统瘫痪。如果使用MQ,系统A不再是直接发送SQL到数据库,而是把数据发送到MQ,MQ短时间积压数据是可以接受的,然后由消费者每次拉取2000条进行处理,防止在请求峰值时期大量的请求直接发送到MySQL导致系统崩溃。
RabbitMQ的核心概念
生产者(Producer):发送消息的应用。
消费者(Consumer):接收消息的应用。
队列(Queue):存储消息的缓存。
消息(Message):由生产者通过RabbitMQ发送给消费者的信息。
连接(Connection):连接RabbitMQ和应用服务器的TCP连接。
通道(Channel):连接里的一个虚拟通道。当你通过消息队列发送或者接收消息时,这个操作都是通过通道进行的。
交换机(Exchange):交换机负责从生产者那里接收消息,并根据交换类型分发到对应的消息列队里。要实现消息的接收,一个队列必须到绑定一个交换机。
绑定(Binding):绑定是队列和交换机的一个关联连接。
路由键(Routing Key):路由键是供交换机查看并根据键来决定如何分发消息到列队的一个键。路由键可以说是消息的目的地址。
RabbitMQ五种消息发送模式
生产者(Producer)发送->中间件->消费者(Consumer)接收消息。
RabbitMQ包括五种队列模式,简单队列、工作队列、发布/订阅、路由、主题、rpc等。
简单队列
生产者将消息发送到队列,消费者从队列获取消息。
一个队列对应一个消费者。
工作队列
- 一个生产者,多个消费者。
- 一个消息发送到队列时,只能被一个消费者获取。
- 多个消费者并行处理消息,提升消息处理速度。 注意:channel.basicQos(1)表示同一时刻只发送一条消息给消费者。 默认采用轮询的方式进行消费。
发布/订阅模式(Publish/Subcribe)
将消息发送到交换机,队列从交换机获取消息,队列需要绑定到交换机。
- 一个生产者,多个消费者。
- 每一个消费者都有自己的一个队列。
- 生产者没有将消息直接发送到队列,而是发送到交换机。
- 每一个队列都要绑定到交换机。
- 生产者发送的消息,经过交换机到达队列,实现一个消息被多个消费者获取的目的。
- 交换机类型为“fanout”。 注意:交换机本身没有存储消息的能力,消息只能存储到队列中。
路由模式(Routing)
路由模式是发布/订阅模式的一种特殊情况。 路由模式的交换机类型为“direct”。 绑定队列到交换机时指定 key,即路由键,一个队列可以指定多个路由键。 生产者发送消息时指定路由键,这时,消息只会发送到绑定的key的对应队列中。
主题模式(Topic)
将路由键和某模式进行匹配。此时,队列需要绑定到一个模式上。
符号“#”匹配一个或多个词,“*”匹配不多不少一个词。
绑定队列到交换机指定key时,进行通配符模式匹配。
远程过程调用 (RPC)
RabbitMQ四种交换机
有4种不同的交换机类型:
- 扇形交换机:Fanout exchange
- 直连交换机:Direct exchange
- 主题交换机:Topic exchange
- 首部交换机:Headers exchange
扇形交换机
扇形交换机是最基本的交换机类型,它所能做的事情非常简单—广播消息。
扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。
因为广播不需要“思考”,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的。
直连交换机
直连交换机是一种带路由功能的交换机,一个队列会和一个交换机绑定,除此之外再绑定一个routing_key,
当消息被发送的时候,需要指定一个binding_key,这个消息被送达交换机的时候,
就会被这个交换机送到指定的队列里面去。同样的一个binding_key也是支持应用到多个队列中的。
这样当一个交换机绑定多个队列,就会被送到对应的队列去处理。
主题交换机
发送到主题交换机上的消息需要携带指定规则的routing_key,
主题交换机会根据这个规则将数据发送到对应的(多个)队列上。
主题交换机的routing_key需要有一定的规则,交换机和队列的binding_key需要采用*.#.*.....的格式,每个部分用.分开,其中:
*表示一个单词
#表示任意数量(零个或多个)单词。
当一个队列的绑定键为#的时候,这个队列将会无视消息的路由键,接收所有的消息。
首部交换机
定义一个Hash的数据结构,消息发送的时候,会携带一组hash数据结构的信息,
当Hash的内容匹配上的时候,消息就会被写入队列
绑定交换机和队列的时候,Hash结构中要求携带一个键“x-match”,这个键的Value可以是any或者all,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键(any)就可以了。相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串(string)。