图 1. 微服务应用开发的生命周期示意如图 1 所示,在微服务架构中,应用程序由一组功能自治的小型化服务围绕业务能力构建,服务之间采用轻量级通信,可以独立开发、构建、测试、发布和监控。微服务的目的是有效拆分应用,实现敏捷开发和部署 [1]。Martin Fowler 和 James Lewis 在《Microservices: A Definition of This New Architectural Term》中,列举了微服务架构的九大特征,如表 1 所示 (参见 [2]),这些特征使得微服务相比于传统软件开发架构,具有更加灵活的设计开发模式,服务之间支持独立部署和扩展,有效提升了企业应用的开发、迭代和运维效率。表 1:微服务架构的九大特征尽管微服务架构秉承众多优秀设计原则,随着应用规模增长、技术生态的成熟和工具链的多元化发展,一系列新的挑战逐渐呈现在企业应用开发者面前。挑战一:开发运维的复杂性高相比于单体(Monolithic)或 SOA(Service-Oriented Architecture)等传统架构下的 “规范标准”,微服务更提倡基于 “实践标准” 解决分布式问题 [2];因此,对于服务注册发现、负载均衡、配置和安全、事务处理等,在微服务场景中不再有统一的解决方案。例如,服务间通信方案就有数十种,包括 REST、gRPC、Thrift、Dubbo 等,服务发现也包含 CoreDNS、Eureka、ZooKeeper、ETCD 等多种技术选型 ; 应用开发人员从这些各有千秋的技术中,选择最适合自己业务场景的系统性方案,无疑是一件门槛很高的任务 ; 尽管有 Spring Cloud 等一站式的全家桶工具集,对应用设计和运维人员来说,一揽子工具集所提供的技术组合复杂多样,导致问题定位、定界效率低。除 Spring Cloud,Kubernetes 也逐渐成为一种主流的微服务解决方案。与 Spring Cloud 相比,Kubernetes 的配置管理和服务注册功能更加友好,且“边车代理模式”、服务网格 (e.g., Istio) 等技术的提出,显著提高了服务治理的效率;但要实现这类解决方案的高效利用,开发者的认知成本和所面对的复杂性并不低;从 Spring Cloud 到 Kubernetes,复杂性没有被减弱,更多地是被转移。微服务架构也需要开发者掌握并发编程框架和分布式事务一致性等技术,这些技术本身具备不低的复杂性,以事务一致性为例,常见机制就包括 TCC (Try-Confirm-Cancel)、2/3PC (2/3 Phase Commit)、SAGA 等模式。挑战二:服务扩展效率与应用规模难平衡尽管微服务提倡对应用进行拆分,但微服务的粒度仍然比较大。同一个微服务单元中,不同子功能之间的使用频率(e.g., QPS、RPS et al.)、变更频率等往往也不相同,因而对扩展性的诉求也不一样。图 2 展示了一个 Web 应用中“用户管理”微服务的例子 [3],该微服务包含账号注册 API、登录 API 和登出 API 三项子功能,在实际使用中,注册 API 和登录 API 的调用频率通常远高于登出 API,因此对扩展性的要求也高于后者;此时虽然可以对微服务进一步进行拆分,但整个应用的服务数量也可能会随之翻倍,从而加重应用基础设施的管理负担。图 2. 一个 Web 应用中“用户管理”微服务的示例微服务粒度较大的问题也使得单个服务的扩容速度十分受限,在高并发场景下要实现微服务的快速弹性是一件十分困难的事;对于时延敏感型应用,并发请求的扩容诉求通常在秒级以内,甚至毫秒级,但在微服务架构下,服务弹性扩容则通常需要秒级以上甚至分钟级的时延。挑战三:高可用与弹性保障成本高与服务扩展效率和应用规模平衡相关的另一个难题是成本问题。受限于单个服务的弹性能力,微服务架构通常采用“多实例主备”或“多实例多活”的方案,来保障应用的高可用性,实现容错、容灾、负载均衡等目标。但与前文中讨论的相似,同一个微服务应用的不同子服务之间,其承载的流量大小、调用频率等的差距也可能很大,因此对资源的横向、纵向扩缩容诉求也不一致,这种差距往往给企业带来无畏的成本浪费。图 3 展示了一个由 6 个功能不可或缺的子服务构建而成的微服务应用, 每个服务运行在虚机或容器中,图中实线表示在给定的一段时间内企业为每个服务所占据的虚机或容器所支付的资源成本,虚线表示服务在业务运行中所实际消耗的资源成本。图 3. 一个微服务应用的资源成本示意在图 3 的示例中,微服务 F 由于被调用的频率很高,其所占据的资源利用率也较高,而微服务 A 则相反,其所占据的资源成本和 F 相差不大(e.g., 2u2G 的容器),但 A 被调用的频率则相对低很多,资源利用率也相应更低。在实际应用开发运维中,为保障高可用性和资源弹性,图中实线与虚线之间通常存在较大的差距,这部分成本是企业为应用所占据但未使用的资源付出的成本,属于一种成本浪费;同时,由于微服务架构通常不支持(一般也不建议)单个服务 “Scale-to-Zero”,且微服务应用逐渐变得越来越 “重”,上述 “资源占而不用” 导致的浪费现象也更加严重。