感谢肥侠、Yi YANG、loveis715、郭斌、李斌、itegel、田向阳、Chris Richardson等对本文的贡献和帮助。
目录:
一、微服务需要编排吗?
二、微服务编排的流程
三、微服务编排的一致性
四、微服务编排的监控工具支撑
一、微服务需要编排吗?
微服务是一种新的软件架构风格。在微服务体系结构中,可以将应用分解为多个较小服务, 各个服务可以由独立的团队进行开发、部署。①
(图片来源于:https://www.nginx.com/blog/introduction-to-microservices/
《The Art of Scalability》(架构即未来))
以一个出租车调度软件为例,最开始是一个单体应用,应用核心是业务逻辑,由定义服务、域对象和事件的模块完成。尽管也是模块化逻辑,但是最终它还是会打包并部署为单体式应用,随着时间增加,功能逐渐增多,代码越来越多,这个软件就会越来越难维护。②
这时使用微服务架构就是不错的选择。一个微服务一般完成某个特定的功能,比如定单管理、客户管理等等。每一个微服务都有自己的业务逻辑和适配器。一些微服务还会发布API给其它微服务和应用客户端使用。其它微服务完成一个Web UI,运行时,每一个微服务实例可能是一个Docker容器。
《The Art of Scalability》(架构即未来) 一书则介绍了一个应用横向扩展所需要遵守的AKF扩展模型。根据AKF扩展模型,横向扩展实际上包含了三个维度,而横向扩展解决方案则是这三个维度上所做工作的结合。X轴表示水平复制,Y轴表示应用功能拆解,Z轴表示按数据拆分。
微服务架构模式对应于代表可扩展模型的Y轴。③
当一个系统采用了微服务架构后,会拆分成很多新的微服务,但原有的业务可能还是没有变化,如何在微服务架构下实现原有的业务?相对于传统架构,微服务架构下更需要通过各微服务之间的协作来实现一个完整的业务流程,可以说服务编排是微服务架构下的必备技能。但是,编排涉及到RPC、分布式事务等等,编排的质量不能仅仅取决于老师傅的手艺,需要有完善的编排框架来支撑。
关于微服务的组合(协调):
编制(Orchestration)—— 面向可执行的流程:通过一个可执行的流程来协同内部及外部的服务交互。通过中心流程来控制总体的目标,涉及的操作,服务调用顺序。
编排(Choreography)—— 面向合作:通过消息的交互序列来控制各个部分资源的交互。参与交互的资源都是对等的,没有集中的控制。④
编制看起来好像没有编排自由,灵活。但是编排也有不完美的地方,编排难调试,并且由于没有预定义流程,所以很难事前保证流程正确性,基本靠事后分析数据来判断。当一个业务流程会嵌入到多个服务中,维护会困难重重。
所以我们认为服务的粒度越小,服务需要组合的可能性越大。
二、微服务编排的流程
在这短短的120行代码中,有25行注释,12行空行,83行功能,包括12次参数校验,18此rpc(包括14次写操作),包括6大业务步骤,主要功能是实现添加一个用户。但是啊但是,这里面绝大部分是没有事务控制的,可想而知,当真的出现数据不一致的时候我们修复的过程是有多头疼。我们不能把代码质量完全寄托于老师傅的手艺,编排完全是有章可循的。
(图片来源:https://www.slideshare.net/)
相比于前面的手工编码的编排,采用图形化的编排,即可以屏蔽代码细节处理,也让整理流程一目了然,下面的是一个个原子服务,原子服务可以提供REST接口或者监听事件,可以通过流程编排这些原子服务来实现一个新的复杂服务。
编排的模型包含:
活动模型(赋值、invoke(调用)、空)
控制模型(顺序、分支、循环、异常抛出、异常捕获、并行)。
编排框架提供了更多方便的活动,比如本地调用、REST调用、同异步调用等活动,从而在使用上更加的方便。
有了这些基本的模型,我们就能方便的编排出复杂的业务流程。
(图片来源:https://www.nginx.com/blog/introduction-to-microservices/)
在调用的时候我们知道有同步和异步的区别,同步实现起来简单,但是在多级级联编排的时候要避免因为某个服务的长响应时间导致雪崩效应,一般可以通过设置合理的超时时间限流和服务熔断策略来避免。
流程编排完成之后,我们还需要给每个被编的服务提供正确的参数,是一个适配的过程。一个编排服务(abcd)由a、b、c、d服务编排而成,每个服务都会有自己的出参入参。适配的过程就是从上下文中给入参赋值以及将出参的结果写入到上下文中。
编排服务执行到不同阶段,组成上下文的模型也是不一样的。从最初服务的开始执行的时候,上下文中只有系统级的参数和入参(请求报文)。到执行完一个被编服务后上下问就会增加这个被编服务的出参(响应报文),执行上下文是一个不断增大的过程。所以适配不仅仅存在与编排服务的入参和被编服务的入参之间,还存在于被编服务和在其之前的服务出参之间。
最直接的莫过于依靠手工编码,完成点到点的映射赋值。只是这种工作没有什么成就感,大多数都是重复劳动。当然,我们作为老师傅还是有一些过人之处的,我们有一种解放双手的武器。这个武器就是元数据,我们通过使用元数据对所有的出参和入参标记着色,然后就可以自动完成同样颜色之间的自动映射。这种标志着色可以靠数据字典实现。
这里的数据字典是指抽象出业务含义的基本数据项,如账户,交易额等。通过这些数据字典可以定义出服务所需的的数据结构(服务参数和服务返回值),这样不同的数据结构之间可以按照数据字典进行自动适配。
(图片来源:https://skyao.gitbooks.io/learning-pinpoint/content/)
随着服务的增多,对调用链的分析也会越来越复杂。在一个由很多微服务组成的系统中,他们之间的调用关系会形成复杂的网络。针对服务化应用全链路追踪的问题,Google发表了Dapper论文,介绍了他们如何进行服务追踪分析。其基本思路是在服务调用的请求和响应中加入ID,标明上下游请求的关系。利用这些信息,可以可视化地分析服务调用链路和服务间的依赖关系。⑤
(图片来源:https://github.com/naver/pinpoint)
通过服务调用追踪生成的服务调用栈,可以查看在哪一步出现了错误,以及发现哪里的调用较慢,进行系统优化。
三、微服务编排的一致性
依据CAP理论,分布式系统需要在可用性(availability)和一致性(consistency)之间做出选择。如果选择提供一致性需要付出在满足一致性之前阻塞其他并发访问的代价。
可用性一般是更好的选择,但是在服务和数据库之间维护数据一致性是非常根本的需求,我们的编排框架应该选择满足最终一致性。补偿模式就是就是一种很好的实现最终一致性的途径。
补偿模式,其核心思想是:针对每个操作,都要注册一个与其对应的补偿操作。一般来说操作本身和其补偿(撤销)操作会在一个事务里完成。当其后续操作失败后,需要按相反顺序完成前面注册的所有撤销操作。
跟2PC比,他的核心价值应该是少了锁资源的代价。流程也相对简单一点。但实际操作中,补偿操作不太好定义,其中间状态处理也会比较棘手。⑥
现在RESTful作为一个轻量级的rpc协议已经被广泛采用,能不能很好的支持RESTful服务的事务一致性也是衡量一个编排框架的是否成熟的一个标准。我们公司的王博士设计了一套RESTful扩展规范来支持补偿模式的事务一致性。通过PATCH的HTTP Method来表示compensation操作,并且支持通过服务来查询编排服务执行的状态。
四、微服务编排的监控工具支撑
这里不给出具体的工具了,只是列出了监控工具可能需要具备的功能:
通过可视化分布式系统的模块和他们之间的相互联系来理解系统拓扑。点击某个节点会展示这个模块的详情,比如它当前的状态和请求数量。
实时监控应用内部的活动线程。
可视化请求和响应数量来定位潜在问题(请求时间段分布、错误请求、响应时长等)。
在分布式环境中为每个调用生成可视图,定位瓶颈和失败点。
查看应用上的其他详细信息,比如CPU使用率,内存/垃圾回收,TPS,和JVM参数。⑦
我们所讲的编排实际是编制,是一种集中式的控制,也就意味着如果被编排的服务有响应缓慢的情况,可能会影响到其他服务。这时候我们需要更快的监控来帮助我们发现这类服务,从而尽早优化。
参考资料:
① https://yq.aliyun.com/articles/2764
② http://dockone.io/article/394
③ http://www.cnblogs.com/loveis715/p/5097475.html
④ http://blog.sciencenet.cn/home.php?mod=space&uid=298436&do=blog&id=278887
⑤ https://yq.aliyun.com/articles/60165
⑥ https://zhuanlan.zhihu.com/p/25933039
⑦ https://skyao.gitbooks.io/learning-pinpoint/content/
王文斌
普元高级软件工程师,代码高手,开源技术爱好者,容器技术专家,曾参与浦发BPM项目、银联PAASV1等项目。
关于EAWorld
微服务,DevOps,元数据,企业架构原创技术分享,EAii(Enterprise Architecture Innovation Institute)企业架构创新研究院旗下官方微信公众号。
微信号:eaworld,长按二维码关注
10月-11月,PWorld系列技术趴还将继续上演。目前,10月28日将在北京举行PWorld MeetUP“移动平台新技术发展新趋势及企业实践”已启动报名,戳“阅读原文”可直达报名页面,并了解更多详情~