服务治理当前有远程Proxy方式、智能客户端方式以及本地Proxy这3种主要承载方式,下面分别讨论这几种方式的优缺点。
微服务下的服务框架基本解决了微服务开发和测试的效率问题,业务人员可以把精力聚焦投入到业务需求上面。多语言服务化背景下,服务治理的基础设施的每一次改动和升级,需要多语言框架的同时升级,这里多语言服务框架的开发、测试和维护的开销有很大的工作量。
由于服务框架以Lib的形式存在,和业务代码存在于一个服务里面,会导致做业务需求的业务人员和负责服务治理的基础设施人员之间仍然会有很多沟通和交互,随着组织和团队的扩大,受康威定律的影响,这个沟通成本会变得不可控。
如何减少多语言接入场景下服务治理基础设施的维护开销,同时减少服务治理基础设施升级对业务的影响,尽量将服务治理和业务解耦,这是微服务架构面前的一个课题。
客户端和服务端通信,客户端和服务端都需要有不少服务治理相关的考虑,比如客户端访问服务端时需要考虑服务发现、流量路由、负载均衡、调用熔断、请求降级、mock支持、请求跟踪等诸多特性,服务端也需要考虑限流、降级、安全、统计等。随着业务迭代发展,客户端和服务端需要支持的服务治理特性越来越多,这会影响业务迭代效率。架构设计上有个不成文的说法,任何软件工程遇到的问题都可以通过增加一个中间层来解决。按照这个说法,可以很自然地想到,微服务架构下,是否可以在客户端和服务端中间增加一个中间层,避免两者直接通信,同时把服务治理相关功能从客户端和服务端代码解耦,移到中间层来,这样服务治理特性的变化收敛在中间代理层,对客户端和服务端透明。
API网关 就是用来解决上述微服务治理的效率问题。API网关封装了服务访问和服务治理相关的具体逻辑,客户端只需要使用简单的访问方式,统一访问API网关,由API网关来代理对后端服务的访问,同时由于服务治理特性统一放到API网关上面,服务治理特性的变更可以做到对客户端透明,一定程度上实现了服务治理等基础特性和业务服务的解耦,服务治理特性的升级也比较容易实现。
为了简化客户端的访问方式,对调用方屏蔽集群访问的复杂度,API网关一般会提供一个VIP,调用方直接使用VIP进行访问,由负载均衡设备负责VIP到API网关地址的映射。
API网关和直接使用服务框架相比,优点是业务使用起来很简单,没有什么入门成本,非常容易上手,对业务来说,简单和效率往往是第一位的;同时API网关也可以屏蔽多语言调用方使用方式的差异,避免了微服务框架语言级别的限制,多语言调用方均可以使用简单一致的调用方式访问后端服务,基本解决了多语言的服务治理问题。
当然API网关在提供便捷的服务访问和服务治理能力的同时,相应地也会有一些问题。
首先,引入API网关,通信层面会增加一跳;如果是采用简单易用的VIP访问方式,还需要加上用于VIP解析的负载均衡服务这一跳,所以通信层面上比原来直接访问后端服务增加了二跳,性能上肯定会有一定的损耗。
其次,通信链路上多一跳就会多一个故障点,会对系统的整体稳定性和可用性有一定的影响。
最后,API网关简单易用的同时,灵活性和定制化支持不太好,很难支持复杂的服务治理定制化需求,比如服务如果想支持动态路由切换,API网关支持起来就有点力不从心。
因此,在业务相对简单,或业务线上部署结构不太复杂时,使用API网关是一个很好的选择,可以简化微服务的开发和运维,提高业务迭代的效率。但业务如果发展到比较复杂时,比如生产环境有多个机房,或者同一个机房内部有全流量环境、小流量环境等多套环境,就会有比较多的路由策略需求和动态路由切换需求,这种情况下就需要探索服务层面是否可以有一种对效率和扩展性更好的平衡方式。
和远程Proxy不同,基于智能客户端的服务框架采用和服务端直连的方式,客户端和服务端直接通信,中间不经过任何节点,不仅性能提升,也增强了稳定性。
服务框架需要支持完善的流量调度和容错设计,同时需要支持常见的服务治理策略,对技术的要求相对较高,对于中小公司来说,开发或维护一款完善的服务框架的开销都是不小的。
除了开发维护成本高之外,服务框架作为Lib和客户端服务绑定在一起,因此是语言相关的,所以每个语言均需要相应的服务框架,这会带来很高的多语言服务治理成本。
另外,由于和客户端服务绑定在一起部署,服务框架的迭代升级相对麻烦,当服务框架进行升级时,使用框架的服务均需要进行升级,对于广泛使用的服务框架来说,这是笔不小的开销,框架和微服务的绑定和耦合,会影响框架自身的迭代和创新。
API网关把服务治理相关特性从服务框架中解耦出来,可以提高效率,但灵活性和扩展性稍差;服务框架可以自如地支持各种服务治理需求,但多语言服务治理支持方面会有很大的开销,同时服务治理特性的升级和维护比较困难。因此,是否有一种机制或方式,能兼顾API网关和服务框架各自的优点,在提高业务开发效率的同时,也能很好地支持微服务治理的扩展性和定制化需求,本地网关应运而生。
本地网关又称为Sidecar,通过在每个服务实例对应的本地机器上部署实现服务治理功能的代理,来实现服务治理能力的快速落地。最有代表性的是Netfilx的微服务中间件Prana,初衷是将Netfilx OSS微服务治理套件的能力,通过HTTP API接口的方式,赋能给非Java语言使用,以很小的开销获得Netfilx OSS体系强大的服务治理能力。受到Netflix Prana的启发,Spring Cloud也推出了Spring Cloud Netflix Sidecar。
和API网关相比,本地网关的访问方式更为简单。①事先给本地网关绑定固定的端口号,业务服务通过“localhost:本地端口号”的方式即可访问,虽然和直接访问服务端相比多了一跳,由于是本地访问,比API网关的性能损耗要小。②由于本地网关每个机器上都会有部署,因此API网关单个节点故障对系统稳定性的影响相对较小。③本地网关和服务部署在一起,具有感知本地部署环境的能力,方便一些业务或者环境相关的服务治理特性的落地,比如机房级别的动态路由调整等。
从效率和扩展性上看,本地网关和API网关相比,都有着不少优势。那么是否意味着本地网关就是一个没有问题的完美方案呢,其实本地网关最大的问题是运维上的复杂度比较高,本地网关节点很多,并且业务服务对本地网关也是强依赖,因此需要对本地网关的部署、监控、升级、高可用保障等,都有一套完善的机制来保障。由于本地网关对运维的要求比较高,需要有一套完善的运维工具体系支撑,之前很长一段时间,这种模式在一些互联网公司中得到采用,如Netfilx、Airbnb等,并没有大规模应用起来。