之前的中台系列文章反思的都是宏观层面,接下来会有选择地拿几个重点内容,讨论中台技术落地层面的点滴。
从技术角度看网关必定是最核心的组件,本文我们就来聊聊API(微服务)网关的选型。
如上图,最开始我们的网关大概会是这样的。请求由云端或自建的负载均衡(LB)服务进入打到微服务网关,微服务网关转发到具体的服务实例。
在这个过程中微服务网关的核心功能有:
-
服务发现及路由
-
认证&鉴权
-
限流、降级、黑白名单、链路跟踪等附加能力
微服务网关选型上多半会使用Spring Cloud Gateway。
这是个很“和谐”的方案,但直到云原生架构的出现,微服务都以容器的形式运行,容器内外地址不同导致上述方案无法有效地支撑。
于是会出现第一种演进方案,如上图所示,LB请求先打到Ingress,然后再转到微服务网关,最后再到服务实例。这一方案将网关部署到了容器内,与服务实例在同一个网络下以实现服务发现及路由,但带来的问题有:性能及稳定性不佳、调用链路长。
调用链路长可以采用上述改进的方案,我们把容器外的LB去掉,直接使用Ingress LB,目前主流的云服务都支持,自建的话可以考虑使用Traefik。
但对性能及稳定性上的损失还是没有解决,这时我会回看微服务网关的作用:服务发现及路由完全可以由k8s的service discovery代替,限流、降级、黑白名单、链路跟踪等附加能力可以由Nginx扩展实现,唯有认证&鉴权需要单独考虑。
所以我们可以演化出上图的方案,将认证&鉴权下放到各个服务实例,通过内置认证&鉴权SDK实现相应能力。这方案好处在于调用链路变短、由K8s自身的service discovery实现服务发现及路由更协调,并且额外的还支持了零信任架构。问题在于微服务本身过重、安全过滤不够前置。
解决微服务本身过重的问题,我们可以按上图优化。认证&鉴权的能力我们打出独立的容器并将其与微服务的容器打到同一个pod中,这样一来在微服务开发过程中并不需要依赖认证&鉴权功能,只在部署时注入,非常的方便。
如果我们做零信任架构,要服务内部访问都做鉴权的话这个方案应该是目前最合适的。
如果不需要考虑这么高级别的安全,那么我们可以使用APISIX、Kong等支持插件化能力的网关把认证&鉴权写成插件形成如上图的方案。请求从LB到Ingress,后者实现了网关的认证&鉴权及附加能力,service discovery实现服务发现及路由能力。这会是一种非常合适的选择。
上文我们介绍了几种API(微服务)网关选型的方案,从大的层面说在云原生环境下微服务及网关都要做轻做薄,传统的Spring Cloud体系、Dubbo体系并不一定是最佳的选择,充分用好K8s自身的能力,用最简单的开发技术实现事半功倍的成效。