消息中间件基本上是互联网公司必用的一个中间件,为什么要使用MQ,当然是因为能给我们的系统带来很多好处。

消息队列简单来说是一种先进先出的数据结构,先简单认识下。

一、应用场景

消息中间件主要应用场景主要三个方面是:异步、解耦、削峰

异步

异步比较好理解,很多公司其实本身系统的并发量还是访问量不一定会很大,但是业务会很复杂,一个动作会牵扯到很多业务,当用户触发某个事件后,后面可能有N个步骤,这些步骤如果都需要一个一个串行去走完,那么用户等待的时间就会非常长,这样,即使系统的使用人数不多,也是不能接受的。

这个时候我们使用消息中间件去做异步处理就很好理解了,当有一个长链条操作时,我们将这个长链条进行拆分,使用异步去处理,举个最常见的例子吧。

用户下单,我们简单可想的后续操作就有很多,如扣除优惠券,增加积分,消息提醒等等,这些操作在客户下单的时候,他不需要马上得到这些结果,我们完全可以进行异步操作。

当然,有人说,这个不是可以用多线程去操作么?其实这个就引出了下一个应用场景

解耦

在程序设计过程中,有一条原则是大家耳熟能详的,高内聚、低耦合,如刚刚说的,虽然用多线程,可以进行异步,但是毕竟是一个流程中去调用,这样系统必定耦合度会比较高,耦合度太高,容错性就低,如上,其中一个系统出错,就会导致整个系统出错,而且如果又要增加业务,那整个系统需要重新发布,而且也需要再进行测试。

消息中间件怎么进行解耦呢?主系统下单完成后,写入消息,其他的系统只要按照需要进行消费即可,这样其他系统出错了也不会影响主业务,也很方便的去增加或减少业务,只要增加消费或去掉消费即可。

削峰

削峰用最常见的秒杀来就很好理解,秒杀会使短时间内使系统面临巨大流量,而平时系统的服务器硬件不需要配置这么高,那我们其他的服务,特别是数据库这些,很容易就被打挂了,这个时候我们使用消息,将访问请求都放到队列中,让业务分散到长时间去处理请求,这样虽然暂时会使得系统变得慢一些,但不会使整个系统直接崩溃。

二、带来的问题

当然,很多事情都有两面性,只有好处没有坏处的事情是很少的,那我们来想想消息会带来哪些问题。

系统可用性降低

这个很好理解,既然引用了MQ,那就存在MQ宕机的情况,这必然就会造成业务影响,这里就要考虑MQ的高可用。

系统复杂度

添加一个组件,必然会带来系统的复杂度,当我们引用一个组件,就要想到它可能带来的问题。加上MQ后,既然是异步调用,那就要考虑消息有没有被重复消费,消息有可能丢失,还有消息的传递顺序。

一致性问题

分布式服务本身都会存在这个问题,A系统处理完业务,通过MQ分发送消息,那每个系统处理,都会有自己的状态,A成功了,B失败了,这样必然就有数据一致性问题。

三、各MQ的比较

目前在市面上比较主流的消息队列中间件主要有,Kafka、ActiveMQ、RabbitMQ、RocketMQ 等这几种。我们可以做个比较。

ActiveMQ 使用比较少了,RabbitMQ语言不是java,这点很要命, Kafka很好用,一般大数据领域使用的非常多,一般规模的话使用RocketMQ,毕竟阿里出品的,生态方面都比较稳。

四、快速入门

理论太多,容易劝退,先跑起来再说。

下载源码

下载二进制文件即可,需要看源码再下载源码:https://rocketmq.apache.org/dowloading/releases/ 

上传到服务器,工作之后还是建议买一台自己的服务器,个人服务器还是很便宜的。

unzip rocketmq-all-4.8.0-bin-release.zip

如果没有安装解压工具,则安装:

 yum install -y unzip zip 

可以修改下解压包名称

mv rocketmq-all-4.8.0-bin-release rocketmq

启动RocketMq

4.1 启动NameServer,以下命令都在bin目录下

# 启动命令,并且常驻内存,nohup 属于后台启动,当前目录下生成 nohup.out 日志文件,也可以指定日志输出位置。
$ nohup sh mqnamesrv &
# 可以直接启动项目
$ sh mqnamesrv :
# 查看启动日志,能看到 "The Name Server boot success" 字样则成功
$ tail -f ~/logs/rocketmqlogs/namesrv.log

RocketMq(一)初识-LMLPHP

 如果显示没有日志文件目录,那说明没有启动成功,是因为默认的初始化内存8G,内存不足导致的

vi  runserver.sh
vi  runbroker.sh

找到设置内存的位置,改成256m即可

4.2 启动 Broker 中间件

# 启动命令,并且常驻内存,nohup 属于后台启动,当前目录下生成 nohup.out 日志文件,也可以指定日志输出位置。
nohup sh mqbroker -n localhost:9876 &
# 直接启动
sh mqbroker -n localhost:9876 :
# 查看启动日志
tail -f ~/logs/rocketmqlogs/broker.log

RocketMq(一)初识-LMLPHP

4.3 测试发送消息

打开两个tab进行命令执行,可以更加直观的查看

测试生产消息

 export NAMESRV_ADDR=localhost:9876
 sh tools.sh org.apache.rocketmq.example.quickstart.Producer

结果如下:

RocketMq(一)初识-LMLPHP

 测试消费者

 export NAMESRV_ADDR=localhost:9876
 sh tools.sh  org.apache.rocketmq.example.quickstart.Consumer 

结果:

RocketMq(一)初识-LMLPHP

4.4 关闭mq

与启动顺序相反进行关闭,先关闭 broker、在关闭 nameserv

sh mqshutdown broker
sh mqshutdown namesrv   

以上就是启动mq的流程,其实还是挺简单的,下面再介绍下几个概念,后面再进行下深入学习。

五、角色介绍

几个基础概念

RocketMq(一)初识-LMLPHP

名字服务(Name Server):名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表。多个Namesrv实例组成集群,但相互独立,没有信息交换。

代理服务器(Broker Server):消息中转角色,负责存储消息、转发消息。代理服务器在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备。代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移和主题和队列消息等。

消息生产者(Producer):负责生产消息,一般由业务系统负责生产消息。一个消息生产者会把业务应用系统里产生的消息发送到broker服务器。RocketMQ提供多种发送方式,同步发送、异步发送、顺序发送、单向发送。同步和异步方式均需要Broker返回确认信息,单向发送不需要。

消息消费者(Consumer):负责消费消息,一般是后台系统负责异步消费。一个消息消费者会从Broker服务器拉取消息、并将其提供给应用程序。从用户应用的角度而言提供了两种消费形式:拉取式消费、推动式消费。

主题(Topic):表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。

04-21 09:31