近些年越来越多的企业开始建设自己的微服务体系,在选型过程中不可避免地会产生路线之争。激进的技术派往往秉持着买新不买旧的思维,坚定地站在服务网格的一边。而相对保守的项目派则会更看重技术的稳定性和易用性,从而主张优先上马传统的微服务方案。如果是你,你会怎么选呢?
在回答之前,不如先来尝试回答几个问题:
什么是微服务?
你所在的企业尝试构建微服务体系的目的是什么?是遇到了什么挑战了吗?
你了解服务网格吗?你知道它是带着怎样的使命诞生的吗?
以上的问题如果你能快速给出答案,我相信你在微服务选型上的结论应该是经过深思熟虑的。如果以上的问题让你迷茫,不如和我一起梳理一下微服务的逻辑。
提到微服务可能大部分人首先想到的是 Spring Cloud、Dubbo 或者 Istio。事实上,这种认识是有一定的局限性。严格来讲微服务就是它字面上的意思,是指微型的服务。而我们常说的 Spring Cloud、Dubbo 和 Istio 则是微服务架构思想的具体实践。当然,只了解这些那简直就是废话文学,我们更想要知道的是我们为什么需要微服务?微服务化可以带来什么好处?
应该说任何一种架构的衍进都会明确指向上一代架构的核心痛点,而微服务最初所针对的痛点就是集中式和紧耦合。所有经历过上一个时代的程序员恐怕都会对系统代码的“牵一发而动全身”印象深刻。
微服务通过将服务拆分成功能相对简单且能互联互通的微型模块,实现了业务的充分解耦,更具独立性的服务拆分方式也使得微服务更符合分布式部署的需求。微服务体系还带来了其他的优势,比如:故障隔离能力提升、可扩展性增强、代码复杂度降低等。从此技术大神们心心念念的高内聚、低耦合有了更亲民的实现方式,而方兴未艾的分布式也有了更多用武之地。
当然像所有的事物一样,微服务也不是完美的。彻底碎片化的服务虽然降低了代码复杂度,却使架构复杂度大大提升了,这就导致服务相互发现和质量问题的追踪变得困难。同时,分布式导致的事务问题也突显出来。对于项目的设计人员而言,如何合理地规划每一个微服务的功能,也变成了一个需要反复纠结的棘手问题。
常常听到有人说服务网格(Service Mesh)是下一代的微服务技术,Service Mesh 会取代以 Spring Cloud 为代表的第一代微服务架构技术。对此笔者有不同的看法。
以 Spring Cloud 为代表的微服务架构与服务网格的最大差异其实在于代码的侵入性。通常情况下 Spring Cloud 架构的程序在设计时需要与业务逻辑通盘考虑,它虽然不会侵入业务,却活跃在业务代码出现的各个角落。
而服务网格技术则完全采用了非入侵的处理方式,sidecar 成为了业务服务的唯一代言人。以前需要业务系统三头六臂才能完成的服务发现、流量治理等工作,现在转为由控制面和 sidecar 组成的这个专业团队来打理了。
由此可见,在解决微服务遇到的问题方面,服务网格技术和以 Spring Cloud 为代表的微服务架构技术的基础思路并没有本质区别,只是在具体的实现路径上面存在明显的差异。
应该承认服务网格技术的出现是基于技术人员对业务与治理能力进一步分离的诉求而产生的,但由此就说服务网格是微服务的2.0时代,还为时尚早。在笔者看来,现阶段服务网格技术更像是微服务技术的半代升级款。
山无常势,水无常形,项目中选择什么样的技术架构并没有一定之规。就像我们上面提到的,老架构必然在使用过程中弊端丛生,而新架构也同样会带来新的问题。不能说最先进的架构就是最好的,同理最古老的架构也并不是没有存在的价值。一切的选择都应该基于企业与项目的现实情况。
那么我们应该考量哪些因素呢?
1. 项目的目的或产品的发展阶段。如果项目的目的在于验证某种技术或业务方案,或者产品尚处于 MVP 验证阶段,请从微服务架构的迷思中移出你的注意力,出于快速开发的考虑单体架构是你最优的选择。
2. 业务的规模和市场预期。微服务当然有足够的优势让人心生向往,但是绝不应该为了技术而选择技术。一个日活足够高的 2C 场景当然需要微服务,一个交易量足够大的 2B 场景也离不开微服务的保障。但是小而美的垂直领域却不一定需要微服务的加持。
3. 技术人员储备。技术的核心价值在于人,对于企业而言进行微服务改造之前最好先盘盘手头的人力资源。Java 语言拥有更多的开发者,人力成本相对较低,Spring Cloud 和 Dubbo 就很适合 Java 程序员较多的企业。Kubernetes和容器技术是当下流行的云原生技术的重要基础,相关的运维人员和开发者的薪资也水涨船高,如果企业中这类人员的积累不错的话,使用与云原生亲和力更强的Service Mesh 方案也很不错。
4. 项目资源情况。项目永远是用有限的资源完成确定范围的工作。一个只会运行在虚拟机环境的项目,其实没有必要强行使用 Service Mesh。一个非 Java 语言开发的系统,也没有必要为了使用 Spring Cloud 而强行重构为 Java 系统。
5. 对请求延迟的容忍程度。Sidecar 在带来便利性的同时,也带来了额外的延时。以 Istio 使用的 Envoy 为例,官方的测试结论为每经过一次 sidecar 就会产生 3ms 左右的延迟,对于一般的应用系统而言 3ms 是一个完全可以接受的数字。但是对于调用链路极深的复杂业务系统而言,链路上的 sidecar 所积累出来的延时将是一个较大的数字。而在一个对延时非常敏感的场景中,3ms 是不是一个可以接受的数字也需要充分考虑。
篇幅有限笔者无法也不可能穷尽所有的情况,以上内容只是抛砖引玉。技术终不过是我们实现现实目的的一种手段而已,善加利用砖头也是一代神兵利器。