Istio是一个服务治理平台,治理的是服务间的访问,只要有访问就可以治理,不在乎这个服务是不是所谓的微服务,也不要求跑在其上的代码是微服务化的。单体应用不满足微服务的若干哲学,用Istio治理也是完全可以的。提起“服务治理”,大家最先想到的一定是“微服务的服务治理”,就让我们从微服务的服务治理说起。
Martin Fowler对微服务的描述是“微服务是以一组小型服务来开发单个应用程序的方法,每个服务都运行在自己的进程中,服务间采用轻量级通信机制(通常用 HTTP 资源API)。这些服务围绕业务能力构建并可通过全自动部署机制独立部署,还共用一个最小型的集中式管理,可用不同的语言开发,并使用不同的数据存储技术”,参见 https://martinfowler.com/articles/microservices.html。
可以看出,微服务在本质上还是分而治之、化繁为简的哲学智慧在计算机领域的一个体现。
如图1-3所示,微服务将复杂的单体应用分解成若干小的服务,服务间使用轻量级的协议进行通信。
这种方式带给我们很多好处:
◎ 从开发视角来看,每个微服务的功能更内聚,可以在微服务内设计和扩展功能,并且采用不同的开发语言及开发工具;
◎ 从运维视角来看,在微服务化后,每个微服务都在独立的进程里,可以自运维;更重要的是,微服务化是单一变更的基础,迭代速度更快,上线风险更小;
◎ 从组织管理视角来看,将团队按照微服务切分为小组代替服务大组也有利于敏捷开发。
图1-3 微服务化
但是,微服务化也给开发和运维带来很大的挑战,因为微服务化仅仅是一种分而治之的方法,业务本身的规模和复杂度并没有变少,反而变多。如图1-4所示,在分布式系统中,网络可靠性、通信安全、网络时延、网络拓扑变化等都成了我们要关注的内容。另外,微服务机制带来了大量的工作,比如服务如何请求目标服务,需要引入服务发现和负载均衡等,以及对跨进程的分布式调用栈进行分布式调用链追踪,等等。总之,简单的事情突然变得复杂了。
图1-4 微服务化带来的分布式问题
这就需要一些工具集来做一些通用的工作,包括服务注册、服务发现、负载均衡等。在原来未微服务化的时候,单体应用的多模块之间根本不需要进程间通信,也不需要服务发现。所以,我们将这些工具集理解为用于解决微服务化带来的新问题似乎更合理一些,但是这些工具集本身并没有带来更多的业务收益。
服务治理的演变至少经过了以下三种形态。
第1种形态:在应用程序中包含治理逻辑
在微服务化的过程中,将服务拆分后会发现一堆麻烦事儿,连基本的业务连通都成了问题。如图1-5所示,在处理一些治理逻辑,比如怎么找到对端的服务实例,怎么选择一个对端实例发出请求等时,都需要自己写代码来实现。这种方式简单,对外部依赖少,但会导致存在大量的重复代码。所以,微服务越多,重复的代码越多,维护越难;而且,业务代码和治理逻辑耦合,不管是对治理逻辑的全局升级,还是对业务的升级,都要改同一段代码。
图1-5 第1种形态:在应用程序中包含治理逻辑
第2种形态:治理逻辑独立的代码
在解决第1种形态的问题时,我们很容易想到把治理的公共逻辑抽象成一个公共库,让所有微服务都使用这个公共库。在将这些治理能力包含在开发框架中后,只要是用这种开发框架开发的代码,就包含这种能力,这就是如图 1-6 所示的 SDK 模式,非常典型的这种服务治理框架就是Spring Cloud。这种形态的治理工具集在过去一段时间里得到了非常广泛的应用。
SDK模式虽然在代码上解耦了业务和治理逻辑,但业务代码和 SDK还是要一起编译的,业务代码和治理逻辑还在一个进程内。这就导致几个问题:业务代码必须和 SDK 基于同一种语言,即语言绑定。例如,Spring Cloud等大部分治理框架都基于Java,因此也只适用于 Java 语言开发的服务。经常有客户抱怨自己基于其他语言编写的服务没有对应的治理框架;在治理逻辑升级时,还需要用户的整个服务升级,即使业务逻辑没有改变,这对用户来说是非常不方便的。
图1-6 第2种形态:治理逻辑独立的代码
此外,SDK对开发人员来说有较高的学习门槛,虽然各种SDK都会讲如何开箱即用,但如果只是因为需要治理逻辑,就让开发人员放弃自己熟悉的内容去学习一套新的语言和开发框架,可能代价有点大。
第3种形态:治理逻辑独立的进程
SDK模式仍旧侵入了用户的代码,那就再解耦一层,把治理逻辑彻底从用户的业务代码中剥离出来,这就是如图1-7所示的Sidecar模式。
图1-7 第3种形态:治理逻辑独立的进程
显然,在这种形态下,用户的业务代码和治理逻辑都以独立的进程存在,两者的代码和运行都无耦合,这样可以做到与开发语言无关,升级也相互独立。在对已存在的系统进行微服务治理时,只需搭配 Sidecar 即可,对原服务无须做任何修改,并且可以对老系统渐进式升级改造,先对部分服务进行微服务化。
比较以上三种服务治理形态,我们可以看到服务治理组件的位置在持续下沉,对应用的侵入逐渐减少,如表1-1所示。
表1-1 三种服务治理形态的比较
微服务作为一种架构风格,更是一种敏捷的软件工程实践,说到底是一套方法论;与之对应的 Istio 等服务网格则是一种完整的实践,Istio 更是一款设计良好的具有较好集成及可扩展能力的可落地的服务治理工具和平台。
所以,微服务是一套理论,Istio是一种实践。但是,Istio是用来解决问题的,并不是微服务理论的一种落地,在实际项目中拿着微服务的细节列表来硬套 Istio 的功能,比如要求Istio治理的服务必须实现微服务的服务注册的一些细节,就明显不太适当。
从场景来看,Istio管理的对象大部分是微服务化过的,但这不是必需的要求。对于一个或多个大的单体应用,只要存在服务间的访问要进行治理,Istio也适用。实际上,传统行业的用户业务需要在容器化后进行服务治理,Istio是用户非常喜欢的形态,因为不用因为服务治理而修改代码,只需将业务搬到 Istio 上即可,如果需要将业务微服务化,则可以渐进式进行。
从能力来看,Istio对服务的治理不只包含在微服务中强调的负载均衡、熔断、限流这些一般治理能力,还包含诸多其他能力,例如本书会重点讲到的提供可插拔的服务安全、可扩展的控制策略、服务运行可观察性等更广泛的治理能力。在 Istio 中提供的是用户管理运维服务需要的能力,而不是在微服务教科书中定义的能力。
所以,过多地谈论Istio和微服务的关系,倒不如多关注Istio和Kubernetes的结合关系。Kubernetes和云原生实际上已经改变或者重新定义了软件开发的很多方面,再想一想微服务世界正在发生的事情,我们也许会慢慢地习惯微服务回归本源,即用更加通用和松散的理论在新的形态下指导我们的工作。