大多数的视频各部门中使用过的消息中间件 包括有 RedisMQ、ActiveMQ、RocketMQ、Kafka 等 本文将选取几个典型的业务介绍一下其使用场景及问题。
最开始使用 RocketMQ 的是计数业务 计数业务需要将客户端的播放量实时计算并展示。当时采用 Redis 进行实时计数 再异步调用数据库进行计数。起初这种模式没什么问题 但是随着业务量变大 数据库压力也进一步增大。甚至有时候数据库机器的 CPU 快被打满了 另外当数据库迁移时 需要暂停写入 计数将面临数据丢失。
这时计数业务迫切需要一个可靠的 能实时消费 且能够堆积的 MQ 来改变这种状况.
当时我们考虑了 RocketMQ 和 Kafka 却最终选择了 RocketMQ 原因请参考下方。
放弃 Kafka 投放业务需要将为用户推荐的内容投放到各个区域 但是推荐业务需要知道用户对于推荐内容的反馈 所以投放业务选择了使用 Kafka 来跟推荐业务交互。但是由于某次机器故障 导致 Kafka 集群发生故障转移 而不幸的是 这个集群的分区数过多 导致转移耗时几分钟才完成。
进而导致业务线程阻塞 服务进入无响应状态。而之后了解到 RocketMQ 即使某个 broker 宕机 消息会发送到其他 broker 不会产生整个集群阻塞情况 后来投放业务就将消息交互全部迁移到了 RocketMQ 上。
之前视频基础服务使用了 RedisMQ 用来通知调用方 视频数据发生了变化 进行数据更新。而redis的消息推送基于 pub/sub 模式 虽然实时性很高 但是却不保证可靠 而且消息不会进行持久化。
这两个缺点就导致了某些情况下 调用方收不到通知 而且消息丢失时基本无据可查。
所以此业务最终放弃了 RedisMQ 转而投向 RocketMQ。RocketMQ 能够保证消息至少被投递一次 而且消息支持持久化 即使客户端重启 仍然可以从上次消费的地方继续消费。
用户视频基础服务之前使用了 ActiveMQ 主要用于通知依赖方数据变更 它的消息体里包含了变更的数据。遗憾的是 当消息量很大时 ActiveMQ 经常出现无法响应的情况 甚至消费者出现长时间接收不到消息的情况。而了解到 RocketMQ 单个 broker 可以承担几十万 TPS 亿级消息堆积时 此业务也迁移到 了RocketMQ 上。
目前使用 RocketMQ 的业务 包括视频基础服务 用户服务 直播业务 付费业务 审核等等业务系统。而 Kafka 大部分只用于日志相关的处理服务上 比如日志上报 业务日志收集等等。
另外 随着 RocketMQ 支持的客户端越来越丰富 也便于我们很多其他语言的业务接入 比如 AI 组使用 python 客户端 一些 GO 开发的业务 使用 GO 客户端等。
初期 我们运维 RocketMQ 基本靠命令行和 RocketMQ-Console。业务方经常来询问的问题包括如下
问题很多 而且千奇百怪
而作为运维人员 除了调查解答业务方的问题之外 在命令行运维 RocketMQ 更让我们小心翼翼。生怕脑子一时糊涂 敲错一个命令 造成大面积故障。随着运维的深入 我们总结了一篇又一篇的使用规范 最佳实践 命名约定 操作步骤等等的文章。但是 随之发现 这些文章对生产效率的提升并不明显。所以与其写文档不如将经验和实践转换为产品 能够更好的服务于业务 因此 MQCloud 应运而生。
先看一下 MQCloud 的定位
它是集客户端 SDK 监控预警 集群运维于一体的一站式服务平台。MQCloud 的系统架构如下
接下来分别说明一下 MQCloud 如何解决上面提到的痛点。
为了实现这个目的 引入了用户 资源两大维度。针对用户和资源加以控制 使不同的用户只聚焦于自己的数据。
通过对不同角色展示不同的视图 使用户可以进行的操作一目了然。
为了保障集群操作的安全性和规范性 所有的操作都会以申请单的形式进入后台审批系统 管理员来进行相关审批 安全性大大提升。
MQCloud 核心功能之一就是监控预警 目前支持如下预警
要想做监控 必须先做统计 为了更好的知道 RocketMQ 集群的运行状况 MQCloud 做了大量的统计工作 大部分依赖于 broker 的统计 主要包括如下几项
下面捡一两点进行一下说明
由于 RocketMQ 并没有提供生产者的流量统计 只提供了 topic 但是并不知道每个生产者的情况 所以 MQCloud 实现了对生产者数据进行统计 通过 RocketMQ 的回调钩子实现 :
主要统计如下信息
统计完成后 定时发送到 MQCloud 进行存储 并做实时监控和展示。
关于统计部分有一点说明 一般耗时统计有最大 最小和平均值 而通常 99% (即 99% 的请求耗时都低于此数值)的请求的耗时情况才能反映真实响应情况。99% 请求耗时统计最大的问题是如何控制内存占用 因为需要对某段时间内所有的耗时做排序后才能统计出这段时间的 99% 的耗时状况。而对于流式数据做这样的统计是有一些算法和数据结构的 例如 t-digest 但是 MQCloud 采用了非精确的但是较为简单的分段统计的方法 具体如下
1、创建一个按照最大耗时预哈希的时间跨度不同的耗时分段数组
第一段 耗时范围 0ms~10ms 时间跨度为 1ms。
第二组 耗时范围 11ms~100ms 时间跨度 5ms。
第三组 耗时范围 101ms~3500ms 时间跨度 50ms。
优点 此种分段方法占用内存是固定的 比如最大耗时如果为3500ms 那么只需要空间大小为96的数组即可缺点 分段精度需要提前设定好 且不可更改。
2、针对上面的分段数组 创建一个大小对应的AtomicLong的计数数组 支持并发统计
3、耗时统计时 计算耗时对应的耗时分段数组下标 然后调用计数数组进行统计即可 参考下图
这样 从计数数组就可以得到实时耗时统计 类似如下
4、然后定时采样任务会每分钟对计数数组进行快照 产生如下耗时数据
5、由于上面的耗时数据天然就是排好序的 可以很容易计算 99%、90%、平均耗时等数据了。
另外提一点 由于 RocketMQ 4.4.0 新增的 trace 功能也使用 hook 来实现 与 MQCloud 的统计有冲突 MQCloud 已经做了兼容。Trace 和统计是两种维度 trace 反映的是消息从生产- 存储- 消费的流程 而 MQCloud 做的是针对生产者状况的统计 有了这些统计数据 才可以做到生产耗时情况展示 生产异常情况预警等功能。
关于集群状况收集主要采用了将nmon自动放置到/tmp目录 定时采用ssh连接到机器执行nmon命令 解析返回的数据 然后进行存储。
上面这些工作就为监控和预警奠定了坚实的数据基础。
针对客户端的一些需求 mq-client 在 rocketmq-client 的基础上进行了开发定制
MQCloud储存了生产者、消费者和集群的关系 通过路由适配 客户端可以自动路由到目标集群上 使客户端对多集群透明。
通过搭建单独的trace集群和定制客户端 使trace数据能够发往独立的集群 防止影响主集群。
通过集成不同的序列化机制 配合MQCloud 客户端无需关心序列化问题。
目前支持的序列化为protobuf和json 并且通过类型检测支持在线修改序列化方式。
通过提供令牌桶和漏桶限流机制 自动开启流控机制 防止消息洪峰冲垮业务端 也为需要精准控制流速的业务提供了方便。
针对生产消息使用hystrix提供了隔离api 使业务端在broker故障时可以避免拖累。
通过对客户端数据进行统计 收集 在MQCloud里进行监控 使客户端任何风吹草动都能及时得知。
通过编码保障 使某些约定 规范和最佳实践得以实现。包括但不限于
手动部署一台 broker 实例没什么问题 但是当实例变多时 手动部署极易出错且耗时耗力。
MQCloud 提供了一套自动化部署机制 包括停止写入 上下线 本地更新 远程迁移 包含数据校验 :
支持一键部署
另外 broker 作为 RocketMQ 的核心 其配置有百项之多 而且好多涉及到性能调优 调整时往往需要根据服务器的状况谨慎调整 MQCloud 开发了配置模板功能来支持灵活的部署项
MQCloud 提供了一整套机器的运维机制 大大提升了生产力。
RocketMQ 从 4.4.0 开始支持 ACL 但是默认没有开启 也就是任何人使用管理工具或 API 就可以直接操纵线上集群。但是开启 ACL 对现有业务影响太大 针对这种情况 MQCloud 进行专门定制。
借鉴 RocketMQ ACL 机制 只针对 RocketMQ 管理员操作加固权限校验
并且支持自定义和热加载管理员请求码 使得非法操作 RocketMQ 集群成为不可能 安全性大大提升。
2broker 通信加固
broker 同步数据代码由于没有校验 存在安全隐患 只要连接 master 监听的 slave 通信端口 发送数据大于 8 个字节 就可能导致同步偏移量错误 代码如下
MQCloud 通过验证数据首包的策略 保障了通信的安全性。
if ((this.byteBufferRead.position() - this.processPostion) 8) {
int pos this.byteBufferRead.position() - (this.byteBufferRead.position() % 8);
long readOffset this.byteBufferRead.getLong(pos - 8);
this.processPostion pos;
HAConnection.this.slaveAckOffset readOffset;
if (HAConnection.this.slaveRequestOffset 0) {
HAConnection.this.slaveRequestOffset readOffset;
log.info( slave[ HAConnection.this.clientAddr ] request offset readOffset);
}
HAConnection.this.haService.notifyTransferSome(HAConnection.this.slaveAckOffset);
}
目前 MQCloud 运维规模如下
MQCloud 在充分考虑和吸收实际业务的需求后 以各个角色聚焦为核心 以全面监控为目标 以满足各业务端需求为己任 在不断地发展和完善。
在 MQCloud 逐渐成熟之后 秉承着服务于社区和吸收更多经验的理念 我们开放了源代码。经过设计和拆分 MQCloud 于 18 年开源了 从第一个版本 release 到现在已经过去两年了 期间随着更新迭代大大小小一共 release 了 20 多个版本。其中不但包含功能更新、bug 修复、wiki 说明等 而且每个大版本都经过详细的测试和内部的运行。之后很多小伙伴跃跃欲试 来试用它 并提出一些建议和意见 我们根据反馈来进一步完善它。
我们将一直遵循我们的目标 坚定的走自己的开源之路
8月14日 RocketMQ x EventMesh Open Day 将在深圳举办。Apache RocketMQ Apache EventMesh(incubating)社区携手分别来自银行、保险、基金、券商顶级金融企业 微众银行、平安人寿、博时基金、国信证券打造金融专场 Open Day。全天议程网罗 RocketMQ 5.0、EventMesh 社区最新动态、以及四大金融企业前沿实践、北京大学同款开源实操体验轻松上手、精美茶歇丰富礼品拿到手软 丰富的整日议程不负夏日好时光。
本文转载自网络,原文链接:https://mp.weixin.qq.com/s/vlOUg46B5bcmToX-fjavJQ...
9月17日,2020云栖大会上,阿里云正式发布工业大脑3.0。 阿里云智能资深产品专家...
在TOP云(zuntop.com)科技租赁过服务器的站长都知道独立服务器在价格上比VPS主...
2020年对于云计算行业来说是突破性的一年,因为公共云供应商增加了收入,而疫情...
很长时间没有更新原创文章了,但是还一直在思考和沉淀当中,后面公众号会更频繁...
一、PostgreSQL行业位置 一 行业位置 首先我们看一看RDS PostgreSQL在整个行业当...
中国最?好的一朵云飘进了华瑞银行。阿里云将进一步助力华瑞银行All in Cloud。 -...
查看表结构,sbtest1有主键、k_1二级索引、i_c二级索引 CREATE TABLE `sbtest1` ...
最近,DevOps的采用导致了企业计算的重大转变。除无服务器计算,动态配置和即付...
定义 this是函数运行时自动生成的内部对象,即调用函数的那个对象。(不一定很准...