削峰填谷-系统解耦-日志架构-秒杀系统的实现方式(消息队列之 RabbitMQ)

Posted YX_blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了削峰填谷-系统解耦-日志架构-秒杀系统的实现方式(消息队列之 RabbitMQ)相关的知识,希望对你有一定的参考价值。

1.简介

RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue Protocol)的开源实现。官网:https://www.rabbitmq.com/getstarted.html

2.核心概念

核心图。主要包含图中的信息

       

 

  • 左侧 P 代表 生产者,也就是往 RabbitMQ 发消息的程序。
  • 中间即是 RabbitMQ,其中包括了 交换机 和 队列。
  • 右侧 C 代表 消费者,也就是往 RabbitMQ 拿消息的程序。

2.1 Message

   消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

2.2 Publisher生产者

    是一个向交换器发布消息的客户端应用程序

2.3 Exchange 交换器 


用来接收生产者发送的消息并将这些消息路由给服务器中的队列.
Exchange有4种类型:direct(默认),fanout, topic, 和headers(不怎么用),不同类型的Exchange转发消息的策略有所区别

2.4 Queue消息队列


用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

2.5 Binding绑定


用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
Exchange和Queue的绑定可以是多对多的关系。

2.6 Connection

网络连接,比如一个TCP连接

2.7 Channel信道


多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,

这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。

2.8 Consumer消费者

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

2.9 Virtual Host

  虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,

拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。

2.9 Broker消息队列服务器实体  

    

 

 

3.运行机制

      AMQP 中增加了 Exchange 和 Binding 的角色。生产者把消息发布到 Exchange 上,消息最终到达队列并被消费者接收,而 Binding 决定交换器的消息应该发送到那个队列

         

3.1 Exchange 分发策略

Exchange分发消息时根据类型的不同分发策略有区别

目前共四种类型:

  • direct、
  • fanout、
  • topic、
  • headers

https://www.rabbitmq.com/getstarted.html 

headers 匹配 AMQP 消息的 header 而不是路由键, headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了 .

所以直接看另外三种类型:

direct

消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。

Direct Exchange 是 RabbitMQ 默认的交换机模式,也是最简单的模式,根据key全文匹配去寻找队列

路由键与队列名完全匹配

       

 

 上图中可以看出: 第一个 X - Q1 就有一个 binding key,名字为 orange; X - Q2 就有 2 个 binding key,名字为 black 和 green。当消息中的 路由键 和 这个 binding key 对应上的时候,那么就知道了该消息去到哪一个队列中。

Ps:为什么 X 到 Q2 要有 black,green,2个 binding key呢,一个不就行了吗? - 这个主要是因为可能又有 Q3,而Q3只接受 black 的信息,而Q2不仅接受black 的信息,还接受 green 的信息。

fanout

每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,

每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。

fanout 类型转发消息是最快的。

    

topic

Topic Exchange 转发消息主要是根据通配符,topic交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。

它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#”和符号“*”。#匹配0个或多个单词,*匹配一个单词

在这种交换机模式下:

  • 路由键必须是一串字符,用句号(.) 隔开,比如说 agreements.us,或者 agreements.eu.stockholm 等。
  • 路由模式必须包含一个 星号(*),主要用于匹配路由键指定位置的一个单词,
  •  比如说,一个路由模式是这样子:agreements..b.*,那么就只能匹配路由键是这样子的:第一个单词是 agreements,第四个单词是 b。
  •  井号(#)就表示相当于一个或者多个单词,例如一个匹配模式是 agreements.eu.berlin.#,那么,以agreements.eu.berlin 开头的路由键都是可以的。

 

3.环境搭建

  属于cs架构,需要安装服务端

因为rabbitmq属于erl语言开发的,所以需要安装erl环境。

https://www.cnblogs.com/ericli-ericli/p/5902270.html 这里面有相似的介绍

官方下载 https://www.rabbitmq.com/install-windows.html 

环境变量和 rabbitmq服务端安装好之后,

停止启动

  net stop RabbitMQ && net start RabbitMQ

  

 

4.demo实现

主要是针对Exchange分发策略 进行demo演示

4.1 默认的实现direct

 

因为是默认实现的,所以就不需要去设置bind (在fanout,topic中需要设置)

结果展示

 

 

4.1.2 一个发送者,多个接收者

将上面的代码稍微小改动。

4.1.3多个发送者,多个接收者

4.1.4传送对象

对象需要序列化,其余的操作都是一样的。

4.2 topic 最常用的策略

topic 是 RabbitMQ 中最灵活的一种方式,可以根据 routing_key 自由的绑定不同的队列

由上图可以看出: 

 

 

4.3 Fanout Exchange

 Fanout 就是我们熟悉的广播模式或者订阅模式,给 Fanout 交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。

发送端的 routing_key 写任何字符都会被忽略

相关配置:

 

运行结果:

demo 样码

https://github.com/xinyanggit/rabbitmq-demo

 

以上是关于削峰填谷-系统解耦-日志架构-秒杀系统的实现方式(消息队列之 RabbitMQ)的主要内容,如果未能解决你的问题,请参考以下文章

MQ应用之解耦

探秘苏宁金融升级版秒杀系统

关于日志的那些事儿

消息中间件漫谈:RocketMQ系统架构及元素

SpringBoot集成rabbitmq

消息队列面试题汇总