ps : 这篇文章比较长,读者还是需要耐心的阅读的。干货多多。

在分布式项目中为了提高性能,也为了实现项目规范,我们都会在处理消息队列的时候引入消息中间件。中间件的作用一个是为了解耦,还有一个是性能提升。消息中间件我们每个人每天都在接触,相信大家都用过美团或者是听过美团。从程序员的角度看美团外卖涉及三方角色。【商家】【骑手】【顾客】。这三者的关系简单理解如下

三角色结构

下面案例会通过代码说明,如下是项目结构
项目结构
rabbit-demo

下订单

今天我们着重介绍下订单的流程,那为什么选择下订单流程而不选择其他两个流程呢。因为派送流程不是消息队列。如果非要规划为消息块我只能认为是消息消费。而发订单呢流程和下订单是一样的。考虑读者应该都是平时点餐的那位。对下订单应该更加的了解。

线下买单

我们想想在美团外卖推出之前我们点餐的过程。是顾客到商家店铺里进行买单消费的。这种模式存在什么弊端。这就必须商家的店铺够大,人手够多才能够让我们消费者不拥堵起来。但是这样就增加了商家的成本。所以在这种局限的条件下我们的线上交易诞生了。
线下交易

线上交易

有了美团我们就只需要在手机点餐,商家就会进行选择行接受,然后出货。这就是下单的一个流程。后面的就是骑手商家流程了。

我们的顾客相当于是在向消息队列中添加消息,消息体就是我们的订单。在美团外卖的系统中同一时刻可能多人点单这就导致商家一时间处理不过来,这是我们的mq就作为一中缓存机制先将顾客的订单本地化,mq按先进先出的顺序将消息有条不紊的派发到只能的商家手中。这就解决我们人多导致订单繁琐的问题了。
好了以上是我们用mq的好处。下面我们通过代码看看mq具体的发送消息的集中方式。
线上交易

mq结构图

结构

环境准备

rabbitmq安装

由于RabbitMQ是用Erlang语言编写的,因此需要先安装Erlang。

  • 通过http://www.erlang.org/downloads获取对应安装文件进行安装
  • 增加环境变量ERLANG_HOME=D:\Program Files\erl9.3(这里的目录是我的安装目录,你要换成自己的目录)
  • 修改环境变量Path,在原来的值后面加上“;%ERLANG_HOME%\bin”

安装完Erlang之后,我们就可以安装RabbitMQ了。

  • 到http://www.rabbitmq.com/install-windows-manual.html下载安装包进行安装
  • 增加环境变量RABBITMQ_HOEM=D:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.5(这里的目录是我的安装目录,你要换成自己的目录)
  • 修改环境变量Path,在原来的值后面加上“;%RABBITMQ_HOME%\sbin”

安装好之后,RabbitMQ就作为一个服务按照默认方式进行启动了

运行命令rabbitmq-plugins enable rabbitmq_management 开启Web管理插件
启动
通过浏览器访问http://localhost:15672,并通过默认用户guest进行登录,密码也是guest,登录后的页面:
浏览器界面

springboot项目搭建

关于springboot的搭建这里就不能细说了。我们直接在zxhtom框架中扩展了。只要在里面添加如下依赖就行了

 <!-- rabbit mq --> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-amqp</artifactId> </dependency> 

然后我们只需要创建一个RabbitConfig类。这个类的作用就是让mq在项目启动初期检查并完成各个组件的创建。既然交给spring完成自然需要在类上加上@Configuration注解。

只需要完成以上操作,我们的mq服务就算是配置完成了。剩下的就应该是生产消费了。
这里比较注意的是RabbitConfig这个类,这个类里到底是什么东西,我们在看代码前我们先来了解下mq的原理。

rabbitmq组件拆装

Queue : 消息队列 , 生产者的直接接触对象。
Exchange : 交换机 , 正常情况消费者是直接接触交换机的。
Routing Key : 生产者和消费者接触的两个不同对象。这就需要routing key 将两者对象进行关联起来
Binding : 通过routing key进行绑定到一起。

下面是消费者、生产者、队列、交换机、rk、binding之间的关系

关系

四种交换机

上面我们了解了mq的内部结构,其实还是很简单的。但是我们mq有的时候有广播模式,有的点对点模式。这些是这么来的呢。对了正是我们本节介绍的内容--交换机。

Direct Exchange

顾名思义就是【直连交换机】。要求发送的消息与一个特定的路由键完全的匹配。如下代码中我们queue1的队列和directExchange交换机通过DIRECTION绑定到了一起。那么我们发送消息是必须将消息标记为DIRECTION

 @Bean public Binding binding1(){     return BindingBuilder.bind(queue1()).to(directExchange()).with(DIRECTIONKEY); }