今年的大多数技术工作基本都是在围绕着技术功能开发进行,关于微服务治理相关部分从事了较多的研究,今晚想做个自己过去一段时间中遇到过的微服务治理问题做一些总结。
微服务的调用链路思考
自己所在的公司采用的微服务远程调用技术主要是基于Dubbo这款RPC开源框架,所以大部分的项目结构都基本是consumer,provider,interface这样的三个模块。
然后早期在做微服务治理的时候,需要观测不同的微服务之间的调用了链路分析,于是就需要深入到各个微服务内部去研究。
微服务的调用链路通常都会呈现如下图所示:
一个A服务调用了B服务,B服务调用再进行远程调用了D,C,E服务,这就造成了一个特点,一个小而简单的数据包请求,换取了大量的响应数据信息。通常我们称请求调用的数据流量为“入度”,响应回来的数据信息流量为“出度”。而微服务调用链路里通常都是出度大于入度许多的一个特点。
但是在进行微服务设计的时候,这样的设计思路又是否合适呢?举个场景来介绍:
用户个人页面大致设计如下所示(画得有些潦草了…)
此时前端需要通过一个get-user-info接口来返回这个页面的数据,那么如果在设计微服务接口时没有过多考虑的话,就有可能会出现以下设计:
大致如图所示,这样的设计会带来的问题有:
Dubbo的getUserInfo函数所返回的UserInfoDTO内部包含了太多业务性的字段,例如用户的等级查询,用户资料查询是属于用户服务provider领域的,周边的人查询则是属于定位服务provider领域的,猜你喜欢数据查询是属于推荐provider领域的。现有的这种链路设计则是同时在用户服务模块中嵌入了额外几个不相干的服务模块关系,这样会把各个微服务之间的关系整得比较复杂。
同时也会带来一些问题:
接口设计的单一原则性没有满足
各个不同的微服务内部的接口比较合理的设计应该是每个接口都各自有各自的职责,尽量互不侵入,职责单一。
无形中增大了出度的数据流量
在返回的UserInfoDTO中,包含了除了用户服务需要关心的字段之外,还会夹杂有特别多的其他业务领域字段代码,导致单个微服务的带宽占用提升。假设用户基础信息只有10个字段,但是额外的推荐数据,周边的人数据占用了200个字段,那么此时额外字段占用的流量则会是核心业务字段的20倍,这些细节点在高并发场景中会对用户查询provider的链接带宽造成不小的压力,如果将这些额外的流量分散到不同的微服务调用连接上则能减少不少的压力。
调用链路耗时增加
在查询周边的人基础信息的时候,web层需要多经过一轮用户provider层,反而会加大整个链路的执行耗时。
综合了以上几点整理,我们不妨可以尝试将接口的设计改良为如下所示:
尽量在web层中做远程调用数据结果集的拼凑组合,这样的好处有:
接口耗时降低,方便接口调用的优化,例如以后这个http接口耗时较久,可以通过异步调用的思路进行优化。
尽量满足微服务接口的单一职责设计。
方便后续的服务扩展。当http的调用流量增大时候,各个微服务的流量承载不会相互牵扯,倘若按照第一种设计,当http层流量增大之后,该调用链路在provider层的流量瓶颈会存在于user-provider的网络带宽中,而现如今拆散之后则将出度流量分散到了各个子服务中,更加方便后续进行优化改良,
微服务相互依赖方面的一些思考
从我早期实习的一家互联网金融企业,再到现在的这家社交产品企业,都是在使用Dubbo作为Rpc通讯技术框架。整体在使用方式上大同小异,都是需要引入第三方应用的interface层依赖包,然后才能获取对应Service对象内部的各类接口信息。
例如一个简单的电商系统,内部按照业务领域划分为多个微服,然后各个微服务内部都会将自己要暴露出现的内容写在interface层模块。
但是如果不对interface层设计做一定的规定就容易出现,mall-user服务的interface层中引入了mall-pay服务的interface层依赖,随着后续不断地迭代会造成微服务相互冗余地越来越严重。
所以尽量要保证interface层的依赖单一,不要引入过多的额外信息。上半年的时候经厉了一次微服务耦合依赖大清理工作,就是将各种相互耦合dependency全部清空了。
除了interface层会有相互依赖之外,在provider层也尽量减少对于第三者微服务的依赖,如果http请求接口中需要用到不同微服务数据的字段信息进行渲染的话,尽量在consumer层进行调用组合,具体的好处在文章上方也有提及过。
监控系统的接入
一家合格的互联网企业,通常都要有一套完善的异常监控系统。就这些年的工作经验来说,个人感觉监控的指标也有一定的讲究。
监控的数据要有价值
市面上有很多各式各样的监控系统,但是为什么只有那么几家店监控系统能够存活下来。我认为监控的数据价值是个关键点。监控的指标如果过多,例如能够监控线上机器100个参数,细化到线程池的名称,cpu的各项指标,那么这个时候如果没有一套好的交互界面,整体的价值就会被人贬低。因为这些数据的价值不容易被使用者们发现。
使用监控的场景主要有哪些
流量监控
线上某些服务的调用流量流量的波动图,峰值统计。
线上异常的告警
告警并不是一旦有异常就通知,需要设置一定的阈值机制,保证告警的有效性。
调用链路的分析
整条调用链路的分析是在异常出现的场景下使用比较多的一个情况,能够通过监控系统去跟踪到整个异常链路的细节点,例如请求的参数,异常出现在哪个服务节点中,链路的各个节点中记录的日志信息。
还有很多东西想写,奈何时间已经比较晚了,剩余的内容后续再做整理吧。