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

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 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 应用发布的完整实操视频。

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
5天前
|
Cloud Native API
微服务引擎 MSE 及云原生 API 网关 2024 年 9 月产品动态
微服务引擎 MSE 及云原生 API 网关 2024 年 9 月产品动态。
|
12天前
|
缓存 监控 API
探索微服务架构中的API网关模式
【10月更文挑战第5天】随着微服务架构的兴起,企业纷纷采用这一模式构建复杂应用。在这种架构下,应用被拆分成若干小型、独立的服务,每个服务围绕特定业务功能构建并通过HTTP协议协作。随着服务数量增加,统一管理这些服务间的交互变得至关重要。API网关作为微服务架构的关键组件,承担起路由请求、聚合数据、处理认证与授权等功能。本文通过一个在线零售平台的具体案例,探讨API网关的优势及其实现细节,展示其在简化客户端集成、提升安全性和性能方面的关键作用。
45 2
|
2天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型加速的今天,云原生技术以其高效、灵活、可扩展的特性成为企业IT架构转型的首选。本文深入探讨了云原生环境下微服务治理的策略与实践路径,旨在为读者提供一个系统性的微服务治理框架,涵盖从服务设计、部署、监控到运维的全生命周期管理,助力企业在云端构建更加稳定、高效的业务系统。 ####
|
3天前
|
Cloud Native API 持续交付
利用云原生技术优化微服务架构
【10月更文挑战第13天】云原生技术通过容器化、动态编排、服务网格和声明式API,优化了微服务架构的可伸缩性、可靠性和灵活性。本文介绍了云原生技术的核心概念、优势及实施步骤,探讨了其在自动扩展、CI/CD、服务发现和弹性设计等方面的应用,并提供了实战技巧。
|
3天前
|
运维 监控 Cloud Native
云原生架构下,微服务治理的艺术与实践####
【10月更文挑战第14天】 在数字化转型的大潮中,云原生技术以其高效、灵活与可扩展性成为企业IT架构的首选。本文深入探讨了云原生架构的核心理念,聚焦于微服务治理的策略与实践,揭示了如何通过精细化管理提升系统的响应速度、稳定性和可维护性。不同于传统的摘要概述,本文摘要旨在直接触及读者关注的核心——即如何在复杂多变的云环境中,实现微服务的高效协同与治理,为读者提供一个清晰的行动指南。 ####
12 1
|
14天前
|
Kubernetes 安全 微服务
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
38 8
|
10天前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 云原生 API 网关 2024 年 09 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
|
12天前
|
Cloud Native 测试技术 持续交付
云原生时代的微服务架构实践
【10月更文挑战第5天】随着云计算的普及,云原生概念逐渐深入人心。微服务架构作为云原生的重要组成部分,它强调服务的小型化、自治性和弹性,以适应快速变化的市场需求。本文将探讨如何在云原生环境中设计并实现高效、可靠的微服务架构,包括选择合适的技术栈和最佳实践,以及如何通过持续集成和持续部署(CI/CD)流程来优化开发和运维工作。
|
13天前
|
Cloud Native jenkins 持续交付
云原生时代的微服务架构实践
【10月更文挑战第4天】随着云计算技术的不断成熟,云原生的概念逐渐深入人心。在这篇文章中,我们将探讨如何利用云原生技术构建高效的微服务架构,并分享一些实践经验和代码示例。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的参考。
|
14天前
|
XML Java 数据格式
如何使用 Spring Cloud 实现网关
如何使用 Spring Cloud 实现网关
23 3