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

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: 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)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
1月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
129 6
|
1月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
51 1
|
20天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
140 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
19天前
|
运维 监控 持续交付
微服务架构解析:跨越传统架构的技术革命
微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型的单体应用拆分为多个小而独立的服务,每个服务都可以独立开发、部署和扩展。
149 36
微服务架构解析:跨越传统架构的技术革命
|
3月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
3月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
1月前
|
消息中间件 供应链 架构师
微服务如何实现低耦合高内聚?架构师都在用的技巧!
本文介绍了微服务的拆分方法,重点讲解了“高内聚”和“低耦合”两个核心设计原则。高内聚强调每个微服务应专注于单一职责,减少代码修改范围,提高系统稳定性。低耦合则通过接口和消息队列实现服务间的解耦,确保各服务独立运作,提升系统的灵活性和可维护性。通过领域建模和事件通知机制,可以有效实现微服务的高效拆分和管理。
57 7
|
1月前
|
JavaScript Java API
深入解析微服务的架构设计与实践
深入解析微服务的架构设计与实践
40 0
|
2月前
|
Kubernetes 安全 微服务
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
使用 Istio 缓解电信 5G IoT 微服务 Pod 架构的安全挑战
67 8
|
2月前
|
消息中间件 负载均衡 Cloud Native
云原生之旅:从容器到微服务的架构演变
在数字化转型的风潮中,云原生技术以其灵活性、可扩展性和弹性而备受青睐。本文将通过一个虚拟的故事,讲述一个企业如何逐步拥抱云原生,实现从传统架构向容器化和微服务架构的转变,以及这一过程中遇到的挑战和解决方案。我们将以浅显易懂的方式,探讨云原生的核心概念,并通过实际代码示例,展示如何在云平台上部署和管理微服务。