RocketMq(一)初识

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

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

一、应用场景

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

异步

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

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

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

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

解耦

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

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

削峰

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

二、带来的问题

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

系统可用性降低

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

系统复杂度

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

一致性问题

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

三、各MQ的比较

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

特性 ActiveMQ RabbitMQ RocketMQ Kafka
开发语言 java erlang java scala
单机吞吐量 万级 万级 10万级 10万级
时效性 ms级 us级 ms级 ms级
可用性 高(主从架构) 高(主从结构) 非常高(分布式架构) 非常高(分布式架构)
消息可靠性 有较低概率丢失数据 基本不丢 经过参数优化,可以做到0丢失 经过参数优化,可以做到0丢失
功能支持 MQ领域的功能极其完备 并发性能强,性能很好,延时低 MQ功能较为完善,分布式,扩展性好 功能较为简单,主要支持简单的MQ功能

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

四、快速入门

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

下载源码

下载二进制文件即可,需要看源码再下载源码://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

 如果显示没有日志文件目录,那说明没有启动成功,是因为默认的初始化内存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

4.3 测试发送消息

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

测试生产消息

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

结果如下:

 测试消费者

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

结果:

4.4 关闭mq

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

sh mqshutdown broker
sh mqshutdown namesrv   

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

五、角色介绍

几个基础概念

 

 

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

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

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

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

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