中国领先的IT技术网站
|
|
创建专栏

微服务在实践中的难点,小米消息推送是如何做的?

通过对小米消息推送的真实案例分享,全面介绍了微服务在具体实践中的关键技术难度和痛点,以及我们的一些具体做法。

作者:小米开发平台|2017-05-09 09:26

小米推送技术负责人夏超在Qcon全球软件开发大会专场上发表演讲—《微服务在小米消息推送的演进》。通过对小米消息推送的真实案例分享,全面介绍了微服务在具体实践中的关键技术难度和痛点,以及我们的一些具体做法。

以下是小编整理出来的夏超老师分享的内容,如果你没有到现场听讲或是想再加深一遍印象,请往下滑动阅读。

微服务化的动机和挑战

原有的单体服务随着业务的发展,模块越来越多,之间的耦合越来越高,严重影响系统的可扩展性,也极大影响团队开发的效率。我们需要将模块做某种程度上重组,即将模块以服务的形式独立出来。一个请求从原来的单个进程中的函数调用,变成了多个进程间的网络通信。由于增加了网络这个不确定性,如何保证系统整体的稳定性,如何在横跨多个服务调用的情况下能够快速的定位和排查问题就成了系统微服务化带来的主要挑战。我们的应对方法就是需要做服务治理。

服务管理

服务的信息通过人工方式进行注册,路由中心通过服务的实例的上报状态来生成路由表。服务的管理主要有以下两点。首先是服务的限流:主要是为了防止拥塞向前传导。其次是服务的发布和升级,必须考虑灰度控制,灰度策略比较灵活(实例级别的,流量级别的和自定义级别的),灰度的策略通过配置中心进行控制。

路由管理

单个集群的路由负载策略是以服务端为主,客户端为辅的做法。服务端的策略是基于实例权重,客户端策略延时自适应的做法。以服务端为主是考虑系统的稳定,也是中心化思想的体现,但也有缺点,就是不能够及时完整的反映路由的情况。当然路由调度中一个重要的点是要防止系统发生雪崩,在这方面采用了服务端和客户端相结合的保护策略。

多个集群之间按照不同的方式合成路由表,提供了跨集群调度的能力,其中包括:多个集群权重混合模式、互备模式和过载保护模式。

链路监控

传统的监控是机器实例粒度的,当请求调用很深时,一旦下游发生问题,整个系统会产生大量的关联报警,严重影响对问题的定位。所以需要对传统的监控升级,改造成基于链路的监控,提高系统的可诊断性。

上图就是一个实例:如果入口服务X发生报警,那么查看整个调用链,找到问题的源头,如这里就是Z1->G0的服务出了问题才导致的整个链路报警。然后根据Z1->G0的调用情况分布(出问题的调用是否集中分布于某台机器,某个机房,错误码的分布情况),来判断问题产生的原因。实践表明,通过错误分布分析,一般能够排除90%左右的问题。剩下就要具体查看失败请求的调用链来调查问题。

由于在我们的消息系统中,调查问题需要全采样,传统的Zipkin集中式调用链解决方案需要消耗大量的存储和带宽,通过改造,将trace的存储分散在各个机器上面,并结合日志系统来保存调用链信息。查找的时候,首先在入口机器上面都搜索一遍,然后根据trace的调用上下游,到下游机器上逐个查找,完成trace的拼接。

有状态服务的改造

一般微服务都是针对无状态服务的,而消息推送服务中,有很多服务本身是有状态的,比如登录状态服务,离线消息服务等。我们需要将这些有状态服务业纳入我们的统一服务治理中。

有状态服务主要考虑服务数据的迁移(扩容缩容都属于数据迁移),我们的做法是定义数据分布的两张视图,迁移前和迁移后的,然后在上面定义各种迁移的状态来控制上游的读写。举例来说,如下图,现在要迁移PARTITION 3的数据从BASE0数据分片到BASE1数据分片。定义了如下状态:

热数据迁移:上游数据对PARTITON 3数据的读采用双读,写入BASE1。

冷数据迁移:维持上游的读写状态,将BASE0上未迁移的数据迁移到BASE1上。

完成迁移:上游数据对PARTITON 3数据的读写均发往BASE1。

总结与感悟

对消息推送系统的微服务化改造,我们的感悟总结以下几点:

1.坏消息传播的慢:限制问题的扩大。比如限流,熔断等策略。

2.坏消息发现的快:快速发现和定位问题。链路监控和链路调查极大提升系统的可诊断性。

3.自动化本身有代价:比如出现极端情况,简单的人工流量调度比一个需要考虑各个极端情况的完美自适应算法更有效。

4.大型系统的微服务治理的顺序是:稳定,易用,高效。

【编辑推荐】

  1. 内部爆料,推送服务的那些“坑”
  2. 消息总线真的能保证幂等?
  3. 在微服务中使用领域事件
  4. 电商网站的快捷支付流程剖析
  5. 简单易用的消息队列框架的设计与实现
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

热门职位+更多

× Python一种神奇的语言