10赞
623
当前位置:  开发笔记 > 编程语言 > 正文

rocketmq(Activemq的缺点以及rocketmq解释)

使用消息中间件可以解决高并发,那是因为消息中间件可以将消息缓存到队列之中。但是当消息过多的时候,几万,几十万消息中间件也可能会宕机,所以我们可以对消息中间件进行集群,在之前的

使用消息中间件可以解决高并发,那是因为消息中间件可以将消息缓存到队列之中。

但是 当消息 过多的时候,几万,几十万...消息中间件也可能会宕机,所以我们可以对消息中间件进行集群,在之前的activemq中

activemq支持jms规范,点对点 发布订阅 消息模型,但是不支持分布式 (不支持集群) ,或者说集群比较麻烦 需要用到zk,activemq消息堆积能力没rocetmq消息堆积能力强  每年的双11 都是经过了验证的

但是 rocetmq 就支持分布式,集群。它的消息队列缓存的消息 比activemq更多

技术图片

在消息中间件集群的时候,生产者可以通过轮询的方式,将生产的消息依次发送到集群中不同的消息中间件,消费的时候,中间件 会均衡的将消息 发送给集群中不同的消费者

 什么是rocketmq:

技术图片

  • 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点。
  • Producer、Consumer、队列都可以分布式。
  • Producer 向一些队列轮流发送消息,队列集合称为 Topic,Consumer 如果做广播消费,则一个 consumer 实例消费这个Topic 对应的所有队列,如果做集群消费,则多个 Consumer 实例平均消费这个 topic 对应的队列集合。
  • 能够保证严格的消息顺序
  • 提供丰富的消息拉取模式
  • 高效的订阅者水平扩展能力
  • 实时的消息订阅机制
  • 亿级消息堆积能力
  • 较少依赖

rocketmq原理:

 说的rocketmq的时候需要说几个名词:

  Producer 消息生产者,负责产生消息,一般由业务系统负责产生消息。

  Consumer 消息消费者,负责消费消息,一般是后台系统负责异步消费。(分两种消费者:一种是调用consumer的拉取方法从broker拉取消息,一种是Consumer 对象注册一个 Listener 接口,一旦收到消息,Consumer 对象立刻回调 Listener 接口方法)

Producer Group 一类 Producer 的集合名称,这类 Producer 通常发送一类消息,且发送逻辑一致

 Consumer Group 一类 Consumer 的集合名称,这类 Consumer 通常消费一类消息,且消费逻辑一致。

  Broker 消息中转角色,负责存储消息,转发消息,一般也称为 Server。在 JMS 规范中称为 Provider。

  Name Server 是一个几乎无状态节点,可集群部署,节点之间无任何信息同步(rocketmq寻址服务)

技术图片

Name Server 是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。 

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

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

Consumer 与 Name Server 集群中的其中一个节点(随机选择)建立长连接,定期从 Name Server 取 Topic 路 由信息,并向 提供 Topic 服务的 Master、Slave 建立长连接,且定时向 Master、Slave 发送心跳。Consumer 既可以从 Master 订阅消息,也可以从 Slave 订阅消息,订阅规则由 Broker 配置决定。

集群消费:

一个 Consumer Group 中的 Consumer 实例平均分摊消费消息。例如某个 Topic 有 9 条消息,其中一个 Consumer Group 有 3 个实例(可能是 3 个进程,或者 3 台机器),那么每个实例只消费其中的 3 条消息

顺序消息:

消费消息的顺序要同发送消息的顺序一致,在 RocketMQ 中,主要的是层部顺序,即一类消息为满足顺 序性,必须 Producer 单线程顺序发送,且发送到同一个队列,这样 Consumer 就可以按照 Producer 收送 的顺序去消费消息。

普通顺序消息:

顺序消息的一种,正常情况下可以保证完全的顺序消息,但是一旦发生通信异常,Broker 重启,由于队列 总数发生发化,哈希取模后定位的队列会发化,产生短暂的消息顺序不一致。 如果业务能容忍在集群异常情况(如某个 Broker 宕机或者重启)下,消息短暂的乱序,使用普通顺序方式比较合适。

严格顺序消:

顺序消息的一种,无论正常异常情况都能保证顺序,但是牺牲了分布式 Failover 特性,即 Broker 集群中只 要有一台机器不可用,则整个集群都不可用,服务可用性大大降低。 如果服务器部署为同步双写模式,此缺陷可通过备机自动切换为主避免,不过仍然会存在几分钟的服务不 可用。(依赖同步双写,主备自动切换,自动切换功能目前还未实现) 目前已知的应用只有数据库 binlog 同步强依赖严格顺序消息,其他应用绝大部分都可以容忍短暂乱序,推 荐使用普通的顺序消息

使用消息中间件需要解决哪些问题:

1.消息的优先级问题:

   规范中描述的优先级是在一个消息队列中,每条消息都有不同的优先级,一般用整数来描述,优先级高的消息先投递,如果消息完全在一个内存队列中,那么在投递前可以按照优先级排序,令优先级高的先投递。 由于RocketMQ 所有消息都是持久化的,所以如果按照优先级来排序,开销会非常大,因此 RocketMQ 没有特 意支持消息优先级,但是可以通过变通的方式实现类似功能,即单独配置一个优先级高的队列,和一个普通优先级 的队列, 将不同优先级发送到不同队列即可。 对于优先级问题,可以归纳为 2 类

1.只要达到优先级目的即可,不是严格意义上的优先级,通常将优先级划分为高、中、低,或者再多几个级 别。每个优先级可以用不同的 topic 表示,发消息时,定不同的 topic 来表示优先级,这种方式可以解决 绝大部分的优先级问题,但是对业务的优先级精确性做了妥协。

2 .严格的优先级,优先级用整数表示,例如 0 ~ 65535,这种优先级问题一般使用不同 topic 解决就非常不合适 。如果要让 MQ 解决此问题,会对 MQ 的性能造成非常大的影响。这里要确保一点,业务上是否确实需 要这种严格的优先级,如果将优先级压缩成几个,对业务的影响有多大?

2.消息有序性:
  消息有序的是一类消息消费时,能按照发送的顺序来消费。例如:一个订单产生了 3 条消息,分别是订单创 建,订单付款,订单完成。消费时,要按照这个顺序消费才能有意义。但是同时订单之间是可以并行消费的。 RocketMQ 可以严格的保证消息有序。

3.消息过滤

Broker 端消息过滤 在 Broker 中,按照 Consumer 的要求做过滤,优点是减少了对于 Consumer 无用消息的网络传输。 缺点是增加了 Broker 的负担,实现相对复杂

Consumer 端消息过滤 这种过滤方式可由应用完全自定丿实现,但是缺点是很多无用的消息要传输到 Consumer 端。

4.消息持久化

 消息中间件通常采用的几种持久化方式:

(1). 持久化到数据库,例如 Mysql。

(2). 持久化到 KV 存储,例如 levelDB、伯克利 DB 等 KV 存储系统。

(3). 文件记彔形式持久化,例如 Kafka,RocketMQ 

(4). 对内存数据做一个持久化镜像,例如 beanstalkd,VisiNotify (1)、(2)、(3)三种持久化方式都具有将内存队列 Buffer 进行扩展的能力,(4)只是一个内存的镜像,作用是当 Broker 挂掉重启后仍然能将之前内存的数据恢复出来。 JMS 和 CORBA Notification 规范没有明确说明如何持久化,但是持久化部分的性能直接决定了整个消息中间件 的性能。 RocketMQ 参考了 Kafka 的持久化方式,充分利用 Linux 文件系统内存 cache 来提高性能。

5.影响消息可靠性的因素:

影响消息可靠性的几种情况: (1). Broker 正常关闭

(2). Broker 异常 崩溃

(3). OS 崩溃

(4). 机器掉电,但是能立即恢复供电情况。

(5). 机器无法开机(可能是 cpu、主板、内存等关键设备损坏)

(6). 磁盘设备损坏。

(1)、(2)、(3)、(4)四种情况都属于硬件资源可立即恢复情况,RocketMQ 在这四种情况下能保证消息不丢,或 者丢失少量数据。 (5)、(6)属于单点故障,且无法恢复,一旦发生,在此单点上的消息全部丢失。RocketMQ 在这两种情况下,通 过异步复制,可保证 99%的消息不丢,但是仍然会有极少量的消息可能丢失。通过同步双写技术可以完全避免单点, 同步双写势必会影响性能,适合对消息可靠性要求极高的场合,例如和账本 相关的应用。 RocketMQ 从 3.0 版本开始支持同步双写。

6.消息延迟

在消息不堆积的情况下,消息到大Broker后。能like到大consumer   rocketmq 使用长轮询pull (拉 )方式,可以保证消息非常实时,消息实时性不低于push(推)

7.关于消息的消费和这回:

每个消息必须投递一次 RocketMQ Consumer 先pull 消息到本地,消费完成后,才向服务器这回回 ack,如果没有消费一定不会 ack 消息

(1). 发送消息阶段,不允许发送重复的消息。

(2). 消费消息阶段,不允许消费重复的消息。 只有以上两个条件都满足情况下,才能认为消息是“Exactly Only Once”,而要实现以上两点,在分布式系统环 境下,不可避免要产生巨大的开销。所以 RocketMQ 为了追求高性能,并不保证此特性,要求在业务上迕行去重, 也就是说消费消息要做到幂等性。RocketMQ 虽然不能严格保证不重复,但是正常情况下很少会出现重复发送、消费情况,只有网络异常,Consumer 启停等异常情况下会出现消息重复。 此问题的本质原因是网络调用存在不确定性,即既不成功也不失败的第三种状态,所以才产生了消息重复性问 题。

8.rocketmq 中Broker消息队列缓存满了:

Broker 的 Buffer 通常的是 Broker 中一个队列的内存 Buffer 大小,这类 Buffer 通常大小有限,如果 Buffer 满 了以后怎举办? 下面是 CORBA Notification 规范中处理方式:

(1).  拒绝新来的消息,向 Producer 这回 RejectNewEvents 错误码。

(2). 按照特定策略丢弃已有消息

RocketMQ 没有内存 Buffer 概念,RocketMQ 的队列都是持久化磁盘,数据定期清除。 对于此问题的解决思路,RocketMQ 同其他 MQ 有非常显著的区别,RocketMQ 的内存 Buffer 抽象成一个无限 长度的队列,不管有多少数据进来都能装得下,这个无限是有前提的,Broker 会定期删除过期的数据,例如 Broker 只保存 3 天的消息,那么这个 Buffer 虽然长度无限,但是 3 天前的数据会被从队尾删除。

9. 回溯消费

回溯消费是指 Consumer 已经消费成功的消息,由于业务上需求需要重新消费,要支持此功能,Broker 在向 Consumer 投递成功消息后,消息仍然需要保留。并且重新消费一般是按照时间维度,例如由于 Consumer 系统故障, 恢复后需要重新消费 1 小时前的数据,那么Broker 要提供一种机制,可以按照时间维度来回退消费进度。 RocketMQ 支持按照时间回溯消费,时间维度精确到毫秒,可以向前回溯,也可以向后回溯。

 

消息中间件的主要功能是异步解耦,迓有个重要功能是挡住前端的数据洪峰,保证后端系统的稳定性,这就要 求消息中间件具有一定的消息堆积能力,消息堆积分以下两种情况:

(1). 消息堆积在内存 Buffer,一旦超过内存 Buffer,可以根据一定的丢弃策略来丢弃消息,如 CORBA Notification 规范中描述。适合能容忍丢弃消息的业务,这种情况消息的堆积能力主要在于内存 Buffer 大小,而且消息 堆积后,性能下降不会太大,因为内存中数据多少对于对外提供的访问能力影响有限。

(2). 消息堆积到持久化存储系统中,例如 DB,KV 存储,文件记彔形式。 当消息不能在内存 Cache 命中时,要不可避免的访问磁盘,会产生大量读 IO,读 IO 的吞吐量直接决定了 消息堆积后的访问能力。 评估消息堆积能力主要有以下四点:

(1). 消息能堆积多少条,多少字节?即消息的堆积容量。

(2). 消息堆积后,收消息的吞吐量大小,是否会受堆积影响?

(3). 消息堆积后,正常消费的 Consumer 是否会受影响?

(4). 消息堆积后,访问堆积在磁盘的消息时,吞吐量有多大?

11分布式事务

已知的几个分布式事务规范,如 XA,JTA 等。其中 XA 规范被各大数据库厂商广泛支持,如 Oracle,Mysql 等。 其中 XA 的 TM 实现佼佼者如 Oracle Tuxedo,在金融、电信等领域被广泛应用。 分布式事务涉及到两阶段提交问题,在数据存储方面的方面必然需要 KV 存储的支持,因为第二阶段的提交回 滚需要修改消息状态,一定涉及到根据 Key 去查找 Message 的动作。RocketMQ 在第二阶段绕过了根据 Key 去查找 Message 的问题,采用第一阶段发送 Prepared 消息时,拿到了消息的 Offset,第二阶段通过 Offset 去访问消息,并修改状态,Offset 就是数据的地址。 RocketMQ 这种实现事务方式,没有通过 KV 存储做,而是通过 Offset 方式,存在一个显著缺陷,即通过 Offset 更改数据,会令系统的脏页过多,需要特别关注。

12. 定时消息

定时消息是指消息发到 Broker 后,不能立刻被 Consumer 消费,要到特定的时间点或者等待特定的时间后才能 被消费。 如果要支持任意的时间精度,在 Broker 层面,必须要做消息排序,如果再涉及到持久化,那么消息排序要不可避免的产生巨大性能开销。 RocketMQ 支持定时消息,但是不支持任意时间精度,支持特定的 level,例如定时 5s,10s,1m 等。 4.15 消息重试 Consumer 消费消息失败后,要提供一种重试机制,令消息再消费一次。Consumer 消费消息失败通常可以分为 有以下几种情况

1. 由于消息本身的原因,例如反序列化失败,消息数据本身无法处理(例如话费充值,当前消息的手机号被注销,无法充值)等。 这种错诨通常需要跳过这条消息,再消费其他消息,而这条失败的消息即使立刻重试消费,99%也不成功, 所以最好提供一种定时重试机制,即过 10s 秒后再重试。

2. 由于依赖的下游应用服务不可用,例如 db 连接不可用,外系统网络不可达等。 遇到这种错误,即使跳过当前失败的消息,消费其他消息同样也会报错。这种情况建议应用 sleep 30s,再 消费下一条消息,这样可以减轻 Broker 重试消息的压力。

文章借鉴:

RocketMQ 开发指南

技术图片

rocketmq(Activemq的缺点以及rocketmq解释)


推荐阅读
  • kettle 数据迁移 (转)
    最近在公司搞一个项目重构迁移问题,旧项目一直在线上跑,重构的项目则还没上线。重构之后数据库表结构,字段,类型等都有变化,而且重构的数据库由oracl改为mysql。这样就设计到数据 ... [详细]
  • 转载请注明出处:王亟亟的大牛之路5号的时候把自己的老版工具类贴了出来,然后今天上午又加了一点内容进去,然后也是简单的几个Button跑下,看看效果。 新增了两个类,一个手机信息类, ... [详细]
  • ASP.NET 本地化 (localization)
    简要:.NET支持Windows和Web应用程序的全球化和本地化。要使应用程序全球化,可以使用System.Globalization命名空间中的类&# ... [详细]
  • Appium是移动端的自动化测试工具,类似于前面提到的Selenium。利用Appium可以驱动Android、iOS等移动设备完成自动化测试,例如模拟点击、滑动、输入等操作。不过 ... [详细]
  • 函数一、函数是什么定义:函数是指一组语句的集合通过一个名字(函数名)封装起来,想要执行这个函数,只需要调用函数名即可。C中的函数叫function,java中的函数叫method, ... [详细]
  • ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 24. Logging
    常用的诊断中间件:UseDeveloperExceptionPageUseStatusCodePages:返回400~600的状态码UseExceptionHandler自定义异常 ... [详细]
  • http:s-macke.github.iojor1kdemosmain.html?userMP10ocGujo&cpuasm&n1&relayURLwss%3A%2F%2Frel ... [详细]
  • 快速搭建LAMP环境
    快速搭建LAMP环境Linux+Apache+MySQL+PHP一组常用来搭建动态网站或者服务器的开源软件,本身都是各自独立的程序,但是因为常被放在一起使用,拥有了越来越高的兼容度 ... [详细]
  • javamysql(5.6)绿色版的应用
    一、配置MySQL数据库1、解压绿色版mysql,如下图二、安装服务1、运行cmd(管理员版本,否则没有权限),如下图2、运行命令mysqld–install安装服务,如下图:如果 ... [详细]
  • 看完知乎轮子哥的编程之路,我只想说,收下我的膝盖。。。
    看完知乎轮子哥的编程之路,我只想说,收下我的膝盖。。。,Go语言社区,Golang程序员人脉社 ... [详细]
  • 操作符_SQL操作符的优化 ... [详细]
  • 前言通过MySQLReplication功能所实现的扩展总是会受到数据库大小的限制,一旦数据库过于庞大,尤其是当写入过于频繁,很难由一台主机支撑的时候,我们还是会面临到扩展瓶颈。这时候, ... [详细]
  • 1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。因为在重新设置MySQL的root密码的期间,MySQL数据 ... [详细]
  • 如何解决《AspectJ可以通过sun.net。*软件包进行编织吗?》经验,为你挑选了1个好方法。 ... [详细]
  • 如何解决《在每个请求上生成ASP.NET包是否正确?》经验,您有什么比较好的解决方法? ... [详细]
author-avatar
额哦哦额llo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有