ESB架构,从支撑几千到百万订单的优化过程( 二 )


ESB架构,从支撑几千到百万订单的优化过程

文章插图
ActiveMQ.png
其中queues/queue/stats/size队列为消费的堆积消息数;queues/queue/stats/consumerCount是消费者的数量 。消费者消息规定的数报警、消息对接数量过多报警;
故障分析通过流量分析和故障检测 , 发现两个点是主要的瓶颈点
  • 业务消息:由于业务需要 , 终端跟云端通过消息进行业务通信(有些业务场景需要云端主动给消息到终端) , 但是消息的通信采用了轮训拉取的方式 , 通过分析有85%的流量都来自于消息的轮训 , 但是由于业务量还不够大 , 这85%的消息轮训里边又80%以上的都是无效的空查询 , 绝大部分都是没有消息 , 这个时候就是空轮训 , 但是整个业务请求还需要过一遍ActiveMQ 。同时消息的查询后端service直接查询MySQL , 这样对于MySQL的压力也非常大
  • 业务账单数据的处理:此业务出故障的次数也比较多 , 我来公司第一次碰到故障就是账单的队列堵了 , 这个的原因主要是账单的数据会引发一连串的数据计算 , 逻辑非常复杂 , 同步计算 , 严重依赖MySQL , consumer消费能力非常容易遇到瓶颈
  • ActiveMQ集群:集群使用的是5.13.0 , 比较老的一个版本 , 对于cluster的支持不太友好 , 只能支持双主模式 , 双主模式经常出故障
处理措施
  • 消息的轮训拉取的方式改造成推的模式 , 通过websocket实现长连接推送消息
  • 账单数据的处理其实类似于一个离线业务 , 不算是在线业务 , 实时性要求不是很高 , 将账单处理的部分从在线的集群剥离 , 独立一个账单处理的集群 , 同时账单的堵塞经常是因为计算复杂 , 数据库瓶颈遇到队列堵塞 , 所以做了读写分离 , 对于账单报表的读取和计算在同一个Mule集群里边做了队列的读写分离 , 避免互相的影响
  • 同时将服务再次做了细粒度的划分:在线/离线、读/写的服务的划分 , 将集群重新的规划 , 尽量保证实时在线业务的高可用
  • 在线业务集群同时部署两个集群 , 做数据隔离 , 但是同时承载业务流量 , 做到服务级别的HA
  • 接入层通过Nginx和openresty做了一些熔断和降级的处理 , 最大限度保证服务的可用性
  • 通过分析可以发现基本服务的瓶颈都会出现在MySQL数据层 , 那么针对这个瓶颈也做了调整 , 读写分离和分库 , 读写分离比较好理解 , 分库的逻辑主要是针对SAAS的特点 , SAAS系统主要是以客户为核心 , 每个客户都有自己的客户标识 , 那么可以天然的通过客户的标识来进行分库的操作
  • ActiveMQ遇到过几次问题 , 首先是内存过高触发流控(AMQ都有类似的自我保护能力)、OOM这种主要是调整JVM的内存设置以及流控的配置
  • ActiveMQ的集群问题 , 双主的模式经常会出现consumer都落到一个节点 , 导致另外一个节点产生的消息无法消费堵塞 , 高版本的ActiveMQ支持多节点的集群模式也解决了类似的BUG , 由于所有的RD都集中在GRPC微服务改造 , 不准备提升版本支持高版本的开发 , 所以只能通过别的方案绕开 , ActiveMQ不采用集群 , 只是用单点+haproxy来实现HA 。
总结
  • 通过上边的优化改造错误 , Mule运行了一年多的时间 , 支撑了订单到百万的业务量 , 同时故障率非常的低 , 保证了SLA
  • 一个完整的大型系统 , 在整个的生命周期内 , 开发交付以后 , 运维、优化、保证可用性阶段的重要性也非常的大 , 需要不停的去学习改造
  • 监控报警系统需要首先部署好 , 避免系统的裸奔 , 只要好的监控报警才能够帮助我们更快速的定位问题、发现问题、优化和改造系统
  • 服务的等级划分非常重要 , 需要最大粒度的去划分 , 然后根据等级做不同的处理
  • 服务的治理、读写分离在系统的很多方面都能用到 , 需要根据实际情况更好的应用到特定的地方
题外话MuleSoft公司成立于2006年 , 最初是实现一个ESB的开发框架并开源 , 框架的名字命名为"Mule" , 由于单纯通过框架和服务支持很难盈利;


推荐阅读