• RocketMQ的基本使用


    1、MQ 的基本介绍

    MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递 —— 生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。

    1.1、MQ的优点

    消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。

    MQ常见优点如下:

    • 应用解耦

    一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。

    系统的耦合性越高,容错性就越低。以电商应用为例,用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用体验。

     

    使用消息队列解耦合,系统的耦合性就会提高了。比如物流系统发生故障,需要几分钟才能来修复,在这段时间内,物流系统将要处理的数据被缓存到消息队列中,用户的下单操作即正常完成。当物流系统回复后,补充处理存在消息队列中的订单消息即可,终端系统感知不到物流系统发生过几分钟故障。

                             

    • 流量削峰

    高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。

    应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提到系统的稳定性和用户体验。

    一般情况,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,这会影响用户体验。而如果使用消息队列将请求缓存起来,等待系统处理完毕后通知用户下单完毕,这样总不能下单体验要好。

    处于经济考量目的:业务系统正常时段的QPS如果是1000,流量最高峰是10000,为了应对流量高峰配置高性能的服务器显然不划算,这时可以使用消息队列对峰值流量削峰。

                            

    • 数据分发

    通过消息队列可以让数据在多个系统更加之间进行流通。数据的产生方不需要关心谁来使用数据,只需要将数据发送到消息队列,数据使用方直接在消息队列中直接获取数据即可。                  

    • 异步

    主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验。

    1.2、MQ的缺点

    MQ 的缺点包含以下几点:

    • 系统可用性降低

      系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。

      问题:如何保证MQ的高可用?

    • 系统复杂度提高

      MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。

      问题:如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

    • 一致性问题

      A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B系统、C系统处理成功,D系统处理失败。

      问题:如何保证消息数据处理的一致性?

    1.3、常见MQ产品及比较

    常见的MQ产品包括Kafka、ActiveMQ、RabbitMQ、RocketMQ。

    2、RocketMQ 的基本介绍

    RocketMQ是阿里巴巴2016年MQ中间件,使用Java语言开发,在阿里内部,RocketMQ承接了例如“双11”等高并发场景的消息流转,能够处理万亿级别的消息。

    3、RocketMQ的基本使用

    3.1、下载安装 RocketMQ

    环境要求:

    • Linux64位系统

    • JDK1.8(64位)

    • 如果是以源码安装的话,需要安装Maven 3.2.x

    提供下载链接:链接:https://pan.baidu.com/s/1V7eghMTMTi0ivD-CPICtjQ  提取码:dzpm    该链接的文件解压后在 资料/rocketmq安装包 目录里可以找到 rocketmq 的安装包。

    我们先在 Linux 系统上将 JDK 安装好后,将 roketmq 上传至 Linux 上,比如上传至:/usr/mysoft 目录下,然后解压安装包:

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

    实际上解压完成后已相当于安装完成,当然我们可以把这些解压后的文件移到我们想要的目录下,比如:/usr/local/rocketmq 目录下,作为我们的软件安装目录:

    mv /usr/mysoft/rocketmq-all-4.4.0-bin-release/ /usr/local/rocketmq/

    3.2、Rocketmq 的目录介绍

    rocketmq 解压后目录结构如下:

    • bin:启动脚本,包括shell脚本和CMD脚本
    • conf:实例配置文件 ,包括broker配置文件、logback配置文件等
    • lib:依赖jar包,包括Netty、commons-lang、FastJSON等

    3.3、启动Rocketmq

    首先进入 rocketmq 解压后目录的 bin 目录下,该目录存放着各个脚本文件。

    1. 启动NameServer
    # 启动NameServer
    nohup sh mqnamesrv &

    示例:

     启动后,可以查看启动日志。如果没有启动过 nameserver ,该启动日志文件是不存在的

    # 查看启动日志
    tail -f ~/logs/rocketmqlogs/namesrv.log

    1. 启动Broker
    # 启动Broker
    nohup sh mqbroker -n localhost:9876 &

    启动完成后可以查看启动日志:

    # 查看启动日志
    tail -f ~/logs/rocketmqlogs/broker.log 

    启动完成后可通过 ps -ef | grep mq 命令查看进程,如果能找到 nameserver 和 broker 则证明两个都启动成功了:

    或者可以通过 jps 命令来查看已启动的 java 进程:

    如果提示 jps 命令不存在,执行以下命令安装 jps 命令:

    yum install -y java-1.8.0-openjdk-devel.x86_64
    
    # 安装后查看jps命令是否存在
    which jps

    如果启动 broker 后仍然找不到 broker 进程,或者是找不到 broker 的启动日志,此时可能是启动失败了,可查看以下分析解决问题。

    3.3.1、启动不成功原因

    在我们启动 broker 后,可能会出现找不到 broker.log 日志文件的情况,这时是因为 broker 并没有启动成功。这是因为RocketMQ默认的虚拟机内存较大,启动Broker可能因为内存不足而导致失败,此时需要编辑如下两个配置文件,将JVM内存调小一点:

    # 编辑runbroker.sh和runserver.sh将JVM默认内存调小
    vi runbroker.sh
    vi runserver.sh

    参考配置:

    JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

    如下为默认 JVM 内存大小

    可以将上面配置调整为以下配置即可:

     调整完成后,重新执行启动 broker 命令即可。

    3.4、测试发送消息和接收消息

    执行下面命令可发送消息:

    #  设置环境变量
    export NAMESRV_ADDR=localhost:9876
    #  通过 bin 目录下的 tools.sh 脚本,使用安装包的Demo发送消息
    sh tools.sh org.apache.rocketmq.example.quickstart.Producer

    执行下面命令可接收消息:

    #  设置环境变量
    export NAMESRV_ADDR=localhost:9876
    #  接收消息
    sh tools.sh org.apache.rocketmq.example.quickstart.Consumer

    执行接收消息命令后,进程不会自动退出,重新发送消息,可以看到接收消息进程可以自动接收到消息。

    3.5、关闭rocketmq

    在安装目录的 bin 目录下执行以下消息可关闭 rocketmq:

    #  关闭NameServer
    sh mqshutdown namesrv
    #  关闭Broker
    sh mqshutdown broker

    4、RocketMQ集群介绍

    4.1、集群涉及各角色介绍(Producer、Consumer、Broker、NameServer、Topic、Message Queue)

    • Producer:消息的发送者;举例:发信者
    • Consumer:消息接收者;举例:收信者
    • Broker:暂存和传输消息;举例:邮局
    • NameServer:管理Broker;举例:各个邮局的管理机构
    • Topic:区分消息的种类;一个发送者可以发送消息给一个或者多个Topic;一个消息的接收者可以订阅一个或者多个Topic消息
    • Message Queue:相当于是Topic的分区;用于并行发送和接收消息

    4.2、 集群特点

    • NameServer是一个几乎无状态节点(即每个节点都是相同的),可集群部署,节点之间无任何信息同步。

    • Broker部署相对复杂,Broker分为Master(主节点)与Slave(从节点),一个Master可以对应多个Slave,但是一个Slave只能对应一个Master。Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerName相同则意味着是同一组的Broker,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameServer集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。

    • Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

    • Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。Consumer接收消息即可以主动从Broker拉取,也可以由Broker主动推送,所以Consumer需定时向Master、Slave发送心跳,以便让Broker知道哪个Consumer节点是在线的,哪个是离线的。

    NameServer 和 Producer、Consumer 的集群搭建比较简单,因为多个节点之间无需信息同步,所以只要启动多个节点集群也就搭建完成。Broker 集群搭建比较复杂,因为有主从节点,主从之间需要信息同步。

    4.2.1、消费者组和生产者组(group)

    RocketMQ 中在使用生产者或者消费者时,可以为他们指定分别指定组。同一组表示具有相同角色的生产者组合或消费者组合,称为生产者组或消费者组。

    生产者组和消费者组不一定要一样,只要消费者订阅和生产者一样的主题 topic,就能接收到生产者的消息。

    • 生产者组:

    通常具有同样属性(处理的消息种类-topic、以及消息处理逻辑流程—分布式多个客户端)的一些producer可以归为同一个group。生产者组的作用是在集群的情况下,一个生产者down之后,本地事务回滚后,可以继续联系该组下的另外一个生产者实例,不至于导致业务走不下去。

    在事务消息机制中,如果发送某条消息的producer-A宕机,使得事务消息一直处于PREPARED状态并超时,则broker会回查同一个group的其他producer,确认这条消息应该commit 还是 rollback。

    • 消费者组:

    类似于前面提到的生产者组的完全相同的作用,消费者被组合在一起并命名消费组。通过消费者组可以实现消息消费的负载均衡和消息容错目标。

    4.3、集群模式

    1)单Master模式

    这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。

    2)多Master模式

    一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:

    • 优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;
    • 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。

    3)多Master多Slave模式(异步)

    每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级)。异步复制也就是说在主节点写入消息成功后就反馈给 producer 已写入成功,然后主节点再同步消息到从节点。

    这种模式的优缺点如下:

    • 优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;
    • 缺点:Master宕机,磁盘损坏情况下会丢失少量消息。

    4)多Master多Slave模式(同步)

    每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:

    • 优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;
    • 缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。

    5、mqadmin管理工具

    RocketMQ 提供有控制台及一系列控制台命令,用于管理员对主题,集群,broker 等信息的管理。

    RocketMQ 安装目录的 bin 目录下有个mqadmin 脚本,可通过执行 ./mqadmin {command} {args} 命令来对集群、主题等信息进行一系列的管理操作。

    5.1、mqadmin命令介绍

    可参考:https://www.cnblogs.com/zyguo/p/4962425.html

    6、集群监控平台搭建

    RocketMQ有一个对其扩展的开源项目incubator-rocketmq-externals,这个项目中有一个子模块叫rocketmq-console,这个便是管理控制台项目了,先将incubator-rocketmq-externals拉到本地,因为我们需要自己对rocketmq-console进行编译打包运行。

    下载项目:

    git clone https://github.com/apache/rocketmq-externals

    打包前需修改该项目的配置文件 src\main\resources\application.properties,修改配置如下:

    rocketmq.config.namesrvAddr=192.168.32.130:9876;192.168.32.131:9876

    编译打包:

    mvn clean package -Dmaven.test.skip=true

    将项目上传至服务器上,启动rocketmq-console:

    java -jar rocketmq-console-ng-1.0.0.jar

    启动成功后,我们就可以通过在服务器上的浏览器通过访问http://localhost:8080进入控制台界面了,类似下图,不过由于没有发送过消息,所以图表都是空的。

  • 相关阅读:
    架构师如何才能够设计一个安全的架构
    Google Analytics实用用小技巧
    如何从Linux系统中删除用户账户
    使用C++编译器的编译流程
    JavaScript中双叹号的使用实例
    Android合并文件的三种方式代码
    自学Linux命令的四种方法
    前端工程师必备实用网站
    给 iOS App 开发者的 39 个开源的 Swift UI 库
    关于iOS项目的一本书
  • 原文地址:https://www.cnblogs.com/wenxuehai/p/15690746.html
Copyright © 2020-2023  润新知