Spring Cloud 如何引入云原生网关,创新微服务架构

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Spring Cloud 如何引入云原生网关,创新微服务架构

作者:赵炳堃(秉钧)


在传统的微服务体系中,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/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 域名。



配置好 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社区交流群:


Higress 社区交流钉钉群中有历次 Higress 社区周会录屏,包括本文中提到的结合 Spring Cloud 应用发布的完整实操视频。

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
15小时前
|
XML Java API
Spring Boot 和 Spring Cloud: 区别与联系
在现代企业级应用开发中,Spring Boot 和 Spring Cloud 是两个非常流行的项目。它们通常被用于构建和部署微服务架构的应用。尽管它们属于同一个大家族 —— Spring,但它们的设计目标和应用场景有所不同。本文将探讨 Spring Boot 和 Spring Cloud 的基本区别和它们之间的联系。
23 9
|
17天前
|
消息中间件 Java 开发者
Spring Cloud Stream解密:流式数据在微服务中的魔力
Spring Cloud Stream解密:流式数据在微服务中的魔力
215 1
|
17天前
|
监控 Java Docker
从零开始,用Docker-compose打造SkyWalking、Elasticsearch和Spring Cloud的完美融合
从零开始,用Docker-compose打造SkyWalking、Elasticsearch和Spring Cloud的完美融合
28 0
|
17天前
|
Java Nacos 开发者
解决Spring Cloud整合Nacos与Gateway的探险之旅
解决Spring Cloud整合Nacos与Gateway的探险之旅
23 0
|
17天前
|
监控 Java 应用服务中间件
网关大解密:探索Spring Cloud Alibaba中Gateway的奥秘
网关大解密:探索Spring Cloud Alibaba中Gateway的奥秘
36 1
|
17天前
|
Java Nacos Maven
从零搭建微服务架构:Spring Boot与Nacos完美整合
从零搭建微服务架构:Spring Boot与Nacos完美整合
33 0
|
18天前
|
云安全 架构师 安全
阿里云云计算架构师ACE认证(Alibaba Cloud Certified Expert - Cloud Architect)考试大纲
介绍阿里云云计算架构师ACE认证(Alibaba Cloud Certified Expert - Cloud Architect)所需具备的知识及学习方法等。
125 2
|
20天前
|
Java Nacos Docker
Spring Cloud Alibaba【什么是Nacos、Nacos Server下载安装 、Docker安装Nacos Server服务、微服务聚合父工程构建】(一)
Spring Cloud Alibaba【什么是Nacos、Nacos Server下载安装 、Docker安装Nacos Server服务、微服务聚合父工程构建】(一)
30 0
|
20天前
|
Java 调度 开发工具
SpringCloud【微服务架构进化论、微服务的拆分规范和原则、为什么选择Spring Cloud、什么是服务治理 】(一)-全面详解(学习总结---从入门到深化)
SpringCloud【微服务架构进化论、微服务的拆分规范和原则、为什么选择Spring Cloud、什么是服务治理 】(一)-全面详解(学习总结---从入门到深化)
69 0
|
2天前
|
人工智能 监控 安全
java基于微服务架构的智慧工地监管平台源码带APP
劳务管理: 工种管理、分包商管理、信息采集、班组管理、花名册、零工采集、 现场统计、考勤管理、考勤明细、工资管理、零工签证
17 4

相关产品

  • 微服务引擎
  • 服务网格