为了应对扩展而实现微服务架构时,每个组织都会遭遇6个问题。Susan Fowler-Rigetti,一名来自Stripe的前Uber工程师在上月于旧金山召开的微服务实践者峰会上详细阐述了这6个问题。
她声称,假如你正在运行的微服务少于100,那么你或许可以规避这些问题,但如果将服务扩展到任意更大的量级,这将带来其自有的问题,为了使系统高效运行,你需要解决它们。
1:组织性孤立和蔓延
Conway法则的反模式表明,公司的组织结构能够映射其软件架构。Fowler-Rigetti称,一家向微服务迁移的公司经常以产生几个孤立的微服务团队告终。另外,由于没有人知道其他团队正在做什么,以及最佳实践无法分享,最终导致技术无方向蔓延。
“微服务开发者和开发者团队就如同微服务一样”,Fowler-Rigetti说,“他们在专注且只做一件事时是非常棒的”。对于特定团队而言这很好,然而当开发者想要改变团队时,它就会成为问题。
Fowler-Rigetti称,她曾听闻改变了团队的开发者说自己像是换到了一家新公司,因为所有的规则都不同了。
2:花式故障
系统越大越复杂,就意味着越容易出现故障,因此这个系统将会失败。它们通常产生于一些点。随着成千上百的微服务被部署,它们中的任何一个均有可能出现问题。
3:资源竞争
微服务向组织提供服务,就如同生态系统一样,它们十分复杂且脆落,Fowler-Rigetti如是说。
硬件和工程资源均是稀缺昂贵的。不像单体应用,微服务无法通过无限制的硬件或者增加人数来解决问题。她说,这起初可能确实有效,但是随着时间的增长,你的微服务的数量越来越多,这将无法适应扩展的需求。
那么当存在成百上千的微服务时,组织应该如何划分优先级?谁得到优先顺序?谁来做决定?
4:关于微服务的误区
这些误解在开发者和经理之间蔓延,这对于脆落的微服务生态而言是十分危险的。
其中最流行的神话:微服务就是狂野西部。你可以做你所想,使用任何代码、数据库、程序语言等,只要你完成工作后,其他服务就能够依赖它。这样做的代价是巨大的,因为系统最终可能以不得不维护多个库和数据库版本。
另一个危险的神话:微服务就是一颗银弹,它们会解决所有问题。Fowler-Rigetti对此作出了否认。微服务应该是公司架构在触及其扩展能力上限时而做出的演进过程中的一步,而非摆脱工程难题的一条捷径。
5:技术蔓延和技术债务
当开发者团队使用不同语言,各自的基础设施以及定制脚本,来构建微服务结构时,组织最终会得到一个巨大的系统,其中任何一件事都会有一千种不同的做法。
它最终可能会是成百上千的微服务,其中的一些正在运行,大部分在维护中,而另一部分则是被遗忘。“你的脚本在机器的某个角落干着只有上帝才会知道的事情,没人会想整理它们”,Fowler-Rigetti说,“他们都希望搭建下一个新玩意”。
至理名言:任何定制化都是不可扩展的。
6:固有的信任缺失
由于微服务存活于复杂的依赖链中,它们互相依赖,并且也没有标准化和通信,因此这里就无法确定依赖是可靠的。她说,根本没有任何方式获知微服务对于生产流量是否可信。
走出困境
如果你是一名开发者,并且正转向微服务,对于上述司空见惯。你要如何走出困境?
第一步,让组织各级买账。为了使微服务切实可行,推行标准化不仅是最佳实践,更是关键使命。它需要在栈的各层被采纳和实施。
接下来,公司需要“贯穿整个组织,在所有微服务上把控高层架构、运维和组织标准,而非以逐个服务为基础”,她解释道。只有当一个微服务符合所有这些标准,它才可被视为“生产就绪”。
标准化诉求
Fowler-Rigetti分享的上图从微服务视角展示了微服务环境的各层级。其中微服务团队只需要工作在第4层。
为了使微服务变为可能,需要将其他内容从中抽象出。这将会制约技术蔓延以及并增加可计量性。
很多人认为他们通过微服务无偿地获取了可扩展性,但当你遇到一个大到疯狂的规模时,就不是如此了。
下一步,需要就“产品就绪”的要求达成一致,并且这些要求需要成为工程文化的一部分。她说,工程师通常视标准化为障碍,但在微服务的新世界里,每个服务都属于一个复杂的依赖连,此时障碍不再。
微服务不应损害整个产品或系统的完整性。
什么使服务成为”产品就绪”?Fowler-Rigetti给出了一个列表:
稳定性
可靠性
可扩展性
性能
容错
灾备
监控
文档
Fowler-Rigetti对此做了深入解释:
稳定性和可靠性
使用微服务,会带来更多的变更和更快的部署,这就导致了不稳定性。她称,一个可靠的微服务应该是能够被其客户、依赖和生态所信任的。她认为稳定性和可靠性是息息相关的,大多数稳定性需求会伴随可靠性需求。一条在进入生产环境前具备多个阶段的部署流水线就是一个很好地的例子。
可扩展性和性能
Fowler-Rigetti称,大多数人认为他们能够通过微服务无偿获得可扩展性,但这对于巨大的规模而言并非如此。随着流量的增加,它们应该得到适当的扩展。
许多语言在设计上就无法做到高效的扩展,因为它们无法做到并发、分区和高效。这使得用那些语言开发的
微服务难以得到合理的扩展。Fowler-Rigetti谢绝指出具体的语言,但她说,“我很肯定自己能想到一些。”
她解释道,可扩展性是指微服务能够处理多少请求(译者:可扩展性是指系统为应对业务增加而对自身进行相应扩展的能力,有些时候也作伸缩性,即在业务缩减的时候,系统规模做相应的收缩),性能则是指服务能够多好地处理这些任务(译者:这应该叫QoS)。一个高性能的服务应该合理地使用资源、高效地处理任务、快速地处理请求。
如果微服务无法得到预期的扩展,那么其出现故障的概率会急剧上升。延迟的增长会导致低下的可用性。
容错和灾备
为了保证可用性这个终极目标,开发者需要确保任何微服务出现故障后均不会导致系统宕掉。因此开发者需要知道所有的故障模式,并且做好备份工作,以应对故障的带来。
成功灾备的关键是健壮的弹性测试,它包括代码测试、负载测试,以及含其它主动性测试的混沌测试。每个故障模式都应该在生产环境中复现,以观察能否“存活”。
给定微服务环境的复杂度和复杂的依赖链,故障是难以避免的(译者:总觉得这句话本来就有问题)。微服务必须能够承受来自内部和外部的故障。
监控和文档
Fowler-Rigetti说,“我发现在微服务架构中,系统的状态永远和上一秒不同。如果你不知晓系统的状态,在系统故障时你将无法得知,这会导致最终的失败。”
拥有一款好的监控工具来展示系统在任意时刻的状态,这是很关键的。缺少良好的监控工具是造成服务中断的第二大原因。
日志是监控的本质部分,因为你将几乎不可能复现bug。知晓发生了什么的唯一方式就是确保你在那时记录了系统的状态。唯一的手段便是合理的日志记录。
这使得我们能够轻松信任服务。
文档对于每个开发者而言都是阻碍,但它确实是关键的。它移除了技术债务,并使得团队新成员能够赶上进度。