作者: 赵炳堃 (秉钧)
在传统的微服务体系中,Spring Cloud Alibaba 和 Zuul 常被用作配合 Spring Cloud 应用的微服务网关。然而,这些传统的 Java 网关在面对大规模流量的场景下仍存在种种问题。例如 Zuul 因为采纳了非异步 IO 的架构,导致了其在面对高流量的状况下容易呈现阻塞的景象,Spring Cloud Gateway 也会在流量很大的状况下产生 Full GC 的状况,导致申请 RT 变长,影响用户体验和业务稳定性。因而咱们须要寻找一个新的选项,来代替这些传统的微服务网关。
Higress: Spring Cloud 生态下微服务网关的新抉择
Higress 是阿里巴巴开源的一款下一代云原生微服务网关。Higress 能够对接多种注册核心,包含 Nacos/Zookeeper/Eureka 等,可能无缝集成 Spring Cloud 利用,对 Dubbo/Sentinel/OpenSergo 等微服务生态也有着深度的集成。与此同时,Higress 采纳 C++ 内核,相比于传统的 Java 网关来说性能更高,更稳固,比照 Spring Cloud Gateway 和 Zuul 来说,性能能够晋升至 2 - 4 倍。另外,Higress 还人造兼容 K8s 的 Ingress/Gateway API 规范,是一款更合乎云原生时代规范的微服务网关。
更多性能压测试验,请参考:https://mp.weixin.qq.com/s/45ZAc5CGfND46Ao3lbHefQ
Higress 无缝对接 Spring Cloud 利用公布实战
在古代软件架构逐步走向微服务化、云原生化的过程中,利用的更新和迭代的频率变得越来越快,如何在尽可能保障用户体验不受影响的状况下实现利用的迭代公布就显得至关重要。目前业界广泛采纳的几种典型的利用公布策略包含蓝绿公布、金丝雀公布、A/B Testing 公布等。接下来本文将介绍如何应用 Higress 来实现 Spring Cloud Alibaba 利用公布的最佳实际。
前提条件
- 装置 Higress,并装置 Istio CRD,参考 Higress 装置部署文档。
- 装置 Naocs,参考 Nacos 装置部署文档。
Higress 反对将 Nacos,Spring Cloud 利用部署于 K8s 集群内,或者独立于 K8s 进行部署。为了演示不便,本文将 Higress,Nacos,Spring Cloud 利用都部署在本地 K8s 集群。
1. 通过 Higress 实现 Spring Cloud 利用的服务发现和路由
1.1. 部署 SpringCloudAlibaba 利用
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-demo-v1
spec:
replicas: 1
selector:
matchLabels:
app: spring-cloud-demo
template:
metadata:
labels:
app: spring-cloud-demo
spec:
containers:
- name: server
image: higress-registry.cn-hangzhou.cr.aliyuncs.com/samples/spring-cloud-demo:v1
imagePullPolicy: IfNotPresent
env:
# 注册到的 nacos 的地址
- name: NACOS_REGISTRY_ADDRESS
value: nacos-server.default.svc.cluster.local
# 注册时携带的 version 元信息
- name: SPRING_CLOUD_NACOS_DEMO_VERSION
value: v1
咱们在 k8s 集群中部署如上 Deployment,其中通过 NACOS_REGISTRY_ADDRESS 和 SPRING_CLOUD_NACOS_DEMO_VERSION 两个环境变量指定了 Nacos 的地址以及注册时携带的 version 元信息。SpringCloud 利用的 application.properties 配置会读取这两个环境变量,如下所示:
spring.cloud.nacos.discovery.server-addr=${NACOS_REGISTRY_ADDRESS}:8848
spring.cloud.nacos.discovery.metadata.version=${SPRING_CLOUD_NACOS_DEMO_VERSION}
1.2. 配置服务起源
Higress 反对多种服务起源,包含 Nacos/Zookeeper/DNS/ 固定 IP,通过创立 Nacos 服务起源,Higress 就能够发现注册到 Nacos 上的服务,从而实现转发申请到这些服务上。
进入 Higress 控制台(http://console.higress.io/), 点击 服务起源 - 创立服务起源 以创立服务起源。这里抉择 Nacos 2.X,而后填写注册核心的地址,端口,命名空间,服务分组等信息。注册核心的地址能够填写 ip 或者域名,本文将 Nacos 部署在本地 K8s 中,通过 K8s service 裸露 Nacos 端口,因而这里填写对应的 service 域名。
Higress 控制台:http://console.higress.io/
配置好 Nacos 服务起源后,咱们能够在服务列表中看到咱们刚刚部署好的利用。
1.3. 创立域名和路由
在 Higress 管制台上点击域名治理 - 创立域名,创立一条 demo.springcloud.com 域名用于后续的拜访。
点击路由配置 - 创立路由,创立一条名为 demo 的路由,域名抉择咱们刚刚创立好的 demo.springcloud.com,指标服务抉择咱们在 1.2 中看到的 Spring Cloud 利用,path 配置为 /version。
1.4. 申请验证
接下来咱们就能够用配置好的路由来拜访 SpringCloud 利用了,在申请时须要将 demo.springcloud.com 域名解析到本地 ip,如下所示,能够胜利失去返回后果。
注:如果您将 Higress 的 80 和 443 端口通过 LoadBalancer 的形式裸露进去,这里须要将本地 ip 替换为对应 LoadBalancer 的 ip,详见 Higress 疾速开始文档。
2. 利用 Higress 进行蓝绿公布
在蓝绿公布中,有两套雷同的运行环境,一套是以后正在应用的生产环境(蓝色环境),另一套是新版本的测试环境(绿色环境)。新版本的代码只在绿色环境中运行,测试通过后,间接将流量切换到绿色环境中,从而实现新版本的上线。与此同时蓝色环境作为热备环境,当绿色环境呈现问题须要回滚时,也能够间接将流量全副再切换回蓝色环境。
2.1. 部署新版本利用
在本地 K8s 集群中 apply 如下资源,以部署 v2 版本的 SpringCloud 利用。
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-demo-v2
spec:
replicas: 1
selector:
matchLabels:
app: spring-cloud-demo
template:
metadata:
labels:
app: spring-cloud-demo
spec:
containers:
- name: server
image: higress-registry.cn-hangzhou.cr.aliyuncs.com/samples/spring-cloud-demo:v2
imagePullPolicy: IfNotPresent
env:
- name: NACOS_REGISTRY_ADDRESS
value: nacos-server.default.svc.cluster.local
- name: SPRING_CLOUD_NACOS_DEMO_VERSION
value: v2
部署结束后,咱们能够在 Higress 控制台的服务列表中看到利用曾经有两个 endpoint 了,如下图所示:
2.2. 为服务划分子集
部署完 v2 版本的利用后,咱们能够在 Nacos 控制台(http://localhost:8848/nacos)上看到 service-provider 这个服务有两个 ip,它们的 metadata 中的 version 字段别离为 v1 和 v2。Higress 能够依据服务的元信息将服务划分为不同的子集(subset),从而将申请转发到新版本或者老版本的利用中去。
在本地 K8s 集群中 apply 如下资源,从而依据利用元信息中的 version 字段将服务划分为 v1 和 v2 两个子集。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: demo
namespace: higress-system
spec:
host: service-provider.DEFAULT-GROUP.public.nacos
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
2.3. 批改 ingress 路由规定
新版本利用上线后,咱们须要把流量全副切到新版本利用中去,这时只须要简略地批改一下咱们在 1.3 中创立的路由即可。咱们能够在本地 K8s 集群中找到如下 ingress 资源,这对应了咱们在 1.3 中创立的那条路由。
咱们间接编辑这条 ingress 资源,将 higress.io/destination 这条 annotation 的 value 改为 service-provider.DEFAULT-GROUP.public.nacos v2,即可将路由的指标服务批改为 v2 子集。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
higress.io/destination: service-provider.DEFAULT-GROUP.public.nacos v2
higress.io/ignore-path-case: "false"
labels:
higress.io/domain_demo.springcloud.com: "true"
higress.io/resource-definer: higress
name: demo
namespace: higress-system
spec:
ingressClassName: higress
rules:
- host: demo.springcloud.com
http:
paths:
- backend:
resource:
apiGroup: networking.higress.io
kind: McpBridge
name: default
path: /version
pathType: Prefix
2.4. 申请验证
咱们再发送申请,能够看到此时失去的是 v2 版本利用的返回后果,如此便实现了新版本的上线公布。
如果发现已上线的新版本呈现问题须要回滚,只须要批改 ingress 路由中的 higress.io/destination,将值更改为 service-provider.DEFAULT-GROUP.public.nacos v1 即可实现回滚。
3. 利用 Higress 进行金丝雀公布
金丝雀公布是将大量的申请引流到新版本上,因而部署新版本服务只需极小数的实例。验证新版本合乎预期后,逐渐调整流量权重比例,使得流量缓缓从老版本迁徙至新版本,期间能够依据设置的流量比例,对新版本服务进行扩容,同时对老版本服务进行缩容,使得底层资源失去最大化利用。
3.1. 批改 ingress 路由规定
Higress 能够通过一条 Ingress 注解轻松实现利用的金丝雀公布。咱们编辑 2.3 中的 ingress 资源,将 ingress 中的 higress.io/destination 注解按如下形式进行批改:
metadata:
annotations:
higress.io/destination: |
80% service-provider.DEFAULT-GROUP.public.nacos v1
20% service-provider.DEFAULT-GROUP.public.nacos v2
这样 Higress 就能够把 80% 的流量转发到 v1 版本的利用,将 20% 的流量转发到 v2 版本的利用。
3.2. 申请验证
间断发送 20 条申请,能够看到 v1 和 v2 的比例合乎咱们在 ingress 中配置的比例。随着灰度的进行,能够逐步调大 v2 版本的流量比例,最终实现新版本的平滑上线。
4. 利用 Higress 进行 A /B Testing 公布
A/ B 测试基于用户申请的元信息将流量路由到新版本,这是一种基于申请内容匹配的灰度公布策略。只有匹配特定规定的申请才会被引流到新版本,常见的做法包含基于 HTTP Header 和 Cookie。基于 HTTP Header 形式,例如 User-Agent 的值为 Android 的申请(来自安卓零碎的申请)能够拜访新版本,其余零碎依然拜访旧版本。基于 Cookie 形式,Cookie 中通常蕴含具备业务语义的用户信息,例如普通用户能够拜访新版本,VIP 用户依然拜访旧版本。
4.1. 批改 ingress 路由规定
在本示例中,咱们通过 HTTP header 中的 User-Agent 对流量进行辨别,将 Android 零碎的流量转发到 v2 版本,其余零碎的流量仍放弃 v1 版本。首先批改 2.3 中名叫 demo 的 ingress 资源,将 higress.io/destination 批改为 v1 版本,代表目前线上的流量全副会打到原来的 v1 版本:
metadata:
annotations:
higress.io/destination: service-provider.DEFAULT-GROUP.public.nacos v1
当新版本部署实现后,再新建一条如下所示的 ingress 路由。这里采纳正则匹配的形式,当 User-Agent 中含有 Android 时,将申请转发到 v2 版本的服务。
kind: Ingress
metadata:
annotations:
higress.io/destination: service-provider.DEFAULT-GROUP.public.nacos v2
higress.io/canary: "true"
higress.io/canary-by-header: "User-Agent"
higress.io/canary-by-header-pattern: ".*Android.*"
higress.io/ignore-path-case: "false"
labels:
higress.io/domain_demo.springcloud.com: "true"
higress.io/resource-definer: higress
name: demo-ab
namespace: higress-system
spec:
ingressClassName: higress
rules:
- host: demo.springcloud.com
http:
paths:
- backend:
resource:
apiGroup: networking.higress.io
kind: McpBridge
name: default
path: /version
pathType: Prefix
4.2. 申请验证
能够看到来自安卓零碎的申请被转发到了 v2 版本,其余零碎仍拜访 v1 版本。
当新版本验证结束须要全量上线时,只须要将 demo 路由的 higress.io/destination 注解批改为 v2 版本,并删除 demo-ab 路由,这样所有流量就都会拜访 v2 版本了。
退出 Higress 和 Spring Cloud Aliaba 社区
Spring Cloud Alibaba 社区交换群:钉钉群号 2415000986
Higress 社区交换群:钉钉群号 7685011250
Higress 社区交换钉钉群中有历次 Higress 社区周会录屏,包含本文中提到的联合 Spring Cloud 利用公布的残缺实操视频。