@Lenciel

采用事件驱动实施微服务架构

事件

我们在实践微服务架构的时候,根本目的是为了在「商业层面」拥有更加敏捷的系统:更容易响应需求变化,更容易添加、发布和尝试新功能,从而跑在竞争对手前面。

要做到敏捷,系统首先必须是自治的(autonomous)。自治性(autonomy)可以说是敏捷系统的一个先决条件:系统的各个部分相互之间如何沟通,当某个部分失败时如何处理和自动恢复等等,都需要自治性。自治性意味着系统的各个部分可以独立运作,对其他系统,团队和流程的依赖都可以 shed:也就是说,对服务 A 的修改不应该影响到依赖它的服务 B,A 服务挂了,B 服务也应该健在。

自治性的系统是微服务架构造就的吗?并不见得:真正成功实践了微服务架构的公司,真正重要的也不是这个技术而是组织架构上的先行。自治的系统,比如开源社区,城市,自由股票市场,甚至是一个迁徙中的鸟群,它们都不断地适应环境,响应变化,在失败案例中不断地学习。

这类被称为「复杂自适应系统(Complex Adaptive Systems)」的系统,是经过科学家专门研究,得出了很多结论的。其中很重要的一个就是,自治的系统会对「事件」作出「响应」。

当有事件发生时,一个自治的系统,不管是蚁群,人类组织,还是一个软件服务,会选择「做什么」或者「不做什么」,来进行响应。整个复杂的系统,都是这些事件在驱动的。这其实也很好理解,想想我们每天醒来,会根据温度穿衣;开车上班,会根据信号灯启停。我们人类的整个生活都是在对各种事件作出响应。

软件系统也可以被构造成这样:独立,自治,容错,可扩展。

从授权到自治,以及最终一致性

在很多分布式系统的实现里面,人们都通过创建一个单一地址空间来适应不稳定的网络环境。这是个从很多方面来看都错误的做法,但是它实现起来要简单一些:通过 RPC 调用,让 remote 的对象处理一些任务,或者请求一些数据。以电商里面结算购物车为例:购物车服务调用计价服务,计价服务可能会调用物流服务,根据发货地区和物流服务商等因素调整价格,同时购物车服务又会调用仓储服务来获取信息和更新货架。这就是所谓的「授权管理」模式:我们调用对数据有修改权限的服务,完成相应的操作。这种模式就意味着大量的全局状态和互斥锁,并且需要大量的事务。

并且,这种基于授权的设计也会导致瓶颈产生:一个服务挂掉,就容易雪崩;不同服务对数据需求不一样的时候,API 越来越乱,或者产生一个大而全的统一 API,提供给每个服务大量不需要的细节数据。

如果我们换个角度来看系统:不是依靠调用方对某个资源或者服务可以行使的权力来驱动系统,而是通过时间和时间轴上发生的事件来驱动系统,就像我们自己的实际生活一样。还是以电商的系统举例,我们的物流服务有没有可能知道目前顺丰在某个区域搞活动,使用顺丰有优惠,然后把这个数据保存在自己的数据库里面,这样每个订单产生时,这些区域的订单默认使用顺丰?如果我们的服务都这样来设计,它们的研发就不需要考虑太多依赖方当前的状态。

最终一致性?

通过事件驱动,而不是通过「just-in-time」的授权查询使得系统里各个服务能够更加自治,更好容错,更有弹性。但是影响复杂自适应系统的自治性的一个因素,也会影响自治的事件驱动系统,那就是时延「delays」。

如果你发现了某个事件已经发生,你立刻就可以做出反应。比如,有车强行变道进入你的车道,你会马上变道避让或者刹车。但是如果在「知道事件发生」这部分有时延,你的反应就没法那么迅速了,比如你正在训家里小朋友,结果没有发现有车变道进来了,就会「咣」…软件系统也一样。

么最终一致性指什么呢?再以购物为例。如果不是事件驱动的,那么如果你往购物车里面添加了某个商品,这时候仓储服务如果出了问题,你的查询没有返回,你就只好死等在那里。但是如果大家都使用事件驱动,你添加购物车的时候,发出了一个事件。这个时候仓储服务不在线,前端上看来,你还是把商品加入了购物车。当仓储系统恢复时,它收到之前那个事件,发现这个商品已经卖光了,这个时候它抛出一个「库存不足」的事件。购物车服务,计费服务等服务就根据当前用户的状态,去消费这个事件(如果没有结算就在结算的时候通知用户,如果已经结算就要退款或者补货等等)。这样让用户不被阻塞,并最终保持状态一致,就叫做最终一致性。

需要的技术

关于事件,延迟和一致性,再多说几句。事件只有在能够保证它们的时序的时候,才是可用的。也就是说,一组事件的时序,必须对于消费方来说是可信的。这涉及分布式系统里面的另外一个难题,对于构建「transactionality」也同样重要,以后再细说。但总的来说,如果事件乱序了,那么我们不做手工的修复就没有保持最终一致性。Martin Kleppmann管这个叫做「perpetual inconsistency」。时延,乱序,是分布式系统里面的两个难题。

Don't touch me

推行微服务架构的最大收益

作为行业里面最火热的名词之一,「微服务架构」在AmazonNetflix等大厂取得的成功,大家算是耳熟能详了。

但是作为 CTO、技术 VP 或者架构师,要把你服务的公司或者项目加入到「实践微服务并取得成功」的列表上,难度其实是很大的。仅仅是把自己的系统打散成多个服务,就有很大的成本。所以 Martin Flower 也提醒过要当心入坑。

所以看到各种会议,博客,社交媒体上实施微服务架构的经验分享时,要明白这里面真正的成功并不在于对各种技术的应用,或者说,在成功利用 Docker、Kubernets 或者 SpringBoot 等等性感的技术之外,微服务架构带来的最大的收益并不简简单单是技术的落地。

最大的收益

微服务架构真正的收益在于形成小而美,能胜任各种职能的扁平化,自组织,自管理的团队,完成在传统组织架构下无法完成的拓展性和创新性工作。

两个披萨的团队

Amazon 的「团队规模应该控制在点两个披萨就可以吃饱」的规则很有名,Jeff Bezos自己说

Managers: We need more communication on and between our teams Bezos: No. Communication is terrible」

要构建自组织的,创新的团队,需要的不是「更多」的沟通而是 更有效的沟通。这点说起来容易也很好听懂,但要做到其实非常难,只要看看你自己手机上那 50 多个工作原因拉的微信群就知道。

但我们可以在团队规模较小的时候开始尝试。所有人一起办公,培养起友谊和信任,产生化学反应互相激发:这样发生group think或者social loafing的几率就会变小很多。

J Richard Hackman在研究了团队和组织之后指出,团队里面的人之间的沟通和人数的关系是:

(n*n-1)/2

如果人数 n 不断增加,顺畅沟通的难度就会变大,团队的效率就会降低。

Hackman 建议的人数是 10 人以内,Amazon 一般是 6-8 个人,海军陆战队是 4 人一个编组:也就是说,人数不需要那么死板的规定,只是应该比较少。

其实要感受这个不需要那么多理论,回忆一下参加一个婚礼时在餐桌上沟通的质量,和跟两三个朋友喝个茶沟通的质量对比一下,就明白小团队的优势。但我还是推荐好好读读 Hackman 关于团队的文章

多功能团队

为什么我们需要一个团队有各种功能,而不是负责开发、测试、产品、运维的某个单一方面?

Bad behavior arises when you abstract people away from the consequences of their actions

创建团队在功能上的清晰分界,就跟告诉住宾馆的人弄脏了房间是服务员来打扫一样,是在鼓励「坏行为」的发生。一个优秀的程序员应该在编写质量上乘的代码的同时,关注可测试性、易维护性、安全性、性能、可扩展性和易用性等多个方面的问题。如果你划分了 DBA、OPS、QA 等职能团队,开发自然而然的就会认为自己把功能实现出来,工作就完毕了,下面的话就会出来:

  • 「我哪有时间测试,那是测试做的」
  • 「数据库的变更找 DBA」
  • 「我只负责这个功能的实现,基础设施和运维负责它的高可用」

要防止这些对话发生在你的团队,就需要引导和宣扬「一专多能」的文化。在很多成功的公司里面(Amazon,Netflix,Facebook,Google)都很强调这点,比如 Amazon 著名的「谁编写,谁负责」。现在行业里面很流行另外一个热词 DevOps,实际上 DevOps 的本质是 Dev 在前的,甚至不应该有专职的DevOps部门

康威定律

软件开发里面,技术问题远没有人的问题难解决。所以康威说:

organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations

要如何打破内部各个团队之间的壁垒呢?除开自顶向下的进行组织架构的变更,还可以尝试内部开源。

内部开源

一旦你打破职能壁垒,构建起小的,多职能的团队,就能够看到这些人为了构造一个高质量的软件系统,一起努力。他们的工作形态其实挺像开源组织的:大家都可以发表意见,都可以贡献代码,对最终的发布负责。

这样的团队形成之后,在他们的输出基本稳定成形后,就可以开始尝试内部开源。

总结

微服务架构的各种成功案例和大家拥抱它的热切姿态,很容易让我们觉得它解决了很大的问题。

其实微服务架构里面很多基本指导原则,SOA 里面都有。但后者最终的失败就在于,虽然技术上有一整套 WS-*的规范,但是却没有在组织结构上做相应的适配,所以陷入了康威定律指出的死路。

技术和流程当然很重要,但是它们的推动,永远是靠人的,因此,组织结构先行,全员参与,共同为建设能够输出高质量系统,快速响应需求变更的团队努力, 这才是实践微服务架构或者 DevOps 对一个公司最大的收益。