作者: 赵炳堃(秉钧)

在传统的微服务体系中,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利用公布的最佳实际。

前提条件

  1. 装置Higress,并装置Istio CRD,参考Higress装置部署文档。
  2. 装置Naocs,参考Nacos装置部署文档。

Higress反对将Nacos,Spring Cloud利用部署于K8s集群内,或者独立于K8s进行部署。为了演示不便,本文将Higress,Nacos,Spring Cloud利用都部署在本地K8s集群。

1. 通过Higress实现Spring Cloud利用的服务发现和路由

1.1. 部署SpringCloudAlibaba利用

apiVersion: apps/v1kind: Deploymentmetadata:  name: spring-cloud-demo-v1spec:  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}:8848spring.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/v1kind: Deploymentmetadata:  name: spring-cloud-demo-v2spec:  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/v1alpha3kind: DestinationRulemetadata:  name: demo  namespace: higress-systemspec:  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/v1kind: Ingressmetadata:  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-systemspec:  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: Ingressmetadata:  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-systemspec:  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 利用公布的残缺实操视频。