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

简介: 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 应用发布的完整实操视频。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
10月前
|
算法 Java 微服务
【SpringCloud(1)】初识微服务架构:创建一个简单的微服务;java与Spring与微服务;初入RestTemplate
微服务架构是What?? 微服务架构是一种架构模式,它提出将单一应用程序划分为一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。 每个服务允许在其独立的进程中,服务于服务间采用轻量级的通信机制互相协作(通常是Http协议的RESTful API或RPC协议)。 每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据上下文,选择合适的语言、工具对其进行构建
756 126
|
10月前
|
负载均衡 算法 Java
【SpringCloud(2)】微服务注册中心:Eureka、Zookeeper;CAP分析;服务注册与服务发现;单机/集群部署Eureka;连接注册中心
1. 什么是服务治理? SpringCloud封装了Netfix开发的Eureka模块来实现服务治理 在传统pc的远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
502 0
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
731 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
10月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
10月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
3660 1
|
运维 NoSQL Serverless
《第四纪元》玩得轻松,构建也轻松 | 阿里云云原生 API 网关、函数计算助力 IGame 快速构建轻休闲游戏
在轻休闲游戏流量波动大、生命周期短的背景下,传统架构难以应对成本与扩展挑战。本文介绍了基于阿里云函数计算 FC 和 Redis 构建的新一代服务器架构,实现弹性伸缩、成本优化与高效运维,助力轻休闲游戏快速迭代与稳定运营,提升开发效率并降低运维复杂度。
《第四纪元》玩得轻松,构建也轻松 | 阿里云云原生 API 网关、函数计算助力 IGame 快速构建轻休闲游戏
|
11月前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
640 1
|
11月前
|
jenkins Java 持续交付
使用 Jenkins 和 Spring Cloud 自动化微服务部署
随着单体应用逐渐被微服务架构取代,企业对快速发布、可扩展性和高可用性的需求日益增长。Jenkins 作为领先的持续集成与部署工具,结合 Spring Cloud 提供的云原生解决方案,能够有效简化微服务的开发、测试与部署流程。本文介绍了如何通过 Jenkins 实现微服务的自动化构建与部署,并结合 Spring Cloud 的配置管理、服务发现等功能,打造高效、稳定的微服务交付流程。
1166 0
使用 Jenkins 和 Spring Cloud 自动化微服务部署
|
11月前
|
Kubernetes Java 微服务
Spring Cloud 微服务架构技术解析与实践指南
本文档全面介绍 Spring Cloud 微服务架构的核心组件、设计理念和实现方案。作为构建分布式系统的综合工具箱,Spring Cloud 为微服务架构提供了服务发现、配置管理、负载均衡、熔断器等关键功能的标准化实现。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
911 0