Nacos + Gateway 实现动态刷新路由

文章目录

  • Nacos + Gateway 实现动态刷新路由
    • 一、一次微服务组件的替换
    • 二、Nacos + Spring Cloud Gateway + loadbalancer + resilience4j + openfeign 整合Demo
      • 2.1 创建工程spring-cloud-gateway-demo
      • 2.2 创建工程provider
      • 2.3 Nacos Server Setup
      • 2.4 启动工程并测试
    • 引用

一、一次微服务组件的替换

原有系统架构中的一些组件因着技术、业务不断的更新迭代已经渐现颓势,为此需要对一些微服务组件进行替换升级。

本文记录了其中的一部分升级过程,有不专业的地方还请指正。

替换项

  1. 服务注册中心:

    Kubernetes DNS → Nacos

  2. 服务配置中心:

    Spring Cloud Config → Nacos

  3. 路由网关:

    Zuul → Spring Cloud Gateway

替换理由

  1. 注册中心

    原有方案是使用linux的DNS作为注册中心,iptables路由表作转发规则。缺点是当iptables路由表逐渐增大时,路由效率会越来越低。

    替代为Nacos后,首先在Spring Cloud Alibaba生态下,Nacos的功能迭代更新以及Bug修复能得到保障,同时能保证在服务增多的同时性能不会有太大的损耗。

    同时Nacos最新的2.x版本已经支持gRPC的服务上/下线方式,能够做到几乎实时的服务上/下线感知,这是之前版本中的心跳机制所不能及的。

    上图摘自某同事PPT

  2. 配置中心

    首先Nacos本身就是一个配置中心,既然已经使用其作为注册中心,那么为了后期便于维护,也没有必要引入别的组件。

    同时Nacos不像Spring Cloud Config需要有一个git仓库来存储配置文件,它自身就提供了存储能力,同时也可以和DB结合使用。

    Nacos还支持基于长轮询的方式来热更新配置文件,结合上Spring Cloud Gateway就能实现动态路由,这也是本文的主题。

    上图还是摘自那位同事PPT

  3. 路由网关

    Zuul 1.x已经不再维护,并且Zuul 2.x Spring官方似乎也无意集成。

    Spring官方提供了一个简单、强大的替代方案——Spring Cloud Gateway。

    网关的本质是对请求进行路由转发,以及对请求进行前置和后置的过滤,它类似于门面模式,接收客户端的所有请求,经过层层过滤后转发到后端的微服务中。

    Spring Cloud Gateway较于Zuul的优势是显而易见的:

    Zuul 1.x采用的是传统的thread per connection,也就是针对每一个请求,会为这个请求专门分配一个线程来处理,直到请求完成后才会释放线程,若后台服务器响应较慢,该线程就会被阻塞,所以性能并不是很好。

    而Spring Cloud Gateway是基于WebFlux开发的响应式网关,WebFlux扫盲可以参考我引用部分WebFlux相关文章。

    网关示意——摘自《Spring Cloud Alibaba 微服务原理与实战》

二、Nacos + Spring Cloud Gateway + loadbalancer + resilience4j + openfeign 整合Demo

因为是整体组件的升级,除了路由网关和注册/配置中心的升级外,本次也对负载均衡器、断路器做了升级,当然后两个并不是本文的重点。

负载均衡升级

Ribbon → loadbalancer

断路器升级

hystrix → resilience4j

2.1 创建工程spring-cloud-gateway-demo

build.gradle

plugins {id 'org.springframework.boot' version '2.5.3'id 'io.spring.dependency-management' version '1.0.11.RELEASE'id 'java'
}group = 'com.individual'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '11'configurations {compileOnly {extendsFrom annotationProcessor}
}repositories {mavenCentral()
}ext {set('springCloudVersion', "2020.0.3")set('springCloudAlibabaVersion', "2021.1")
}dependencies {implementation 'org.springframework.boot:spring-boot-starter-data-jpa'implementation 'org.springframework.boot:spring-boot-starter-jdbc'implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'implementation 'org.springframework.cloud:spring-cloud-starter-gateway'implementation 'org.springframework.boot:spring-boot-starter-tomcat'implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config'implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'implementation 'mysql:mysql-connector-java'compileOnly 'org.projectlombok:lombok'developmentOnly 'org.springframework.boot:spring-boot-devtools'annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'annotationProcessor 'org.projectlombok:lombok'testImplementation 'org.springframework.boot:spring-boot-starter-test'testImplementation 'io.projectreactor:reactor-test'
}dependencyManagement {imports {mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}"}
}test {useJUnitPlatform()
}

bootstrap.yml

因为application相关配置都放到nacos,所以一些前置配置都放在bootstrap.yml文件中

新版的spring-boot中使用bootstrap务必引用'org.springframework.cloud:spring-cloud-starter-bootstrap'

spring:application:name: spring-cloud-gateway-democloud:nacos:discovery:server-addr: localhost:8848config:server-addr: localhost:8848file-extension: ymlshared-configs[0]:data-id: gateway-routes.yml # 配置文件名-Data Idgroup: DEFAULT_GROUP   # 默认为DEFAULT_GROUPrefresh: true   # 是否动态刷新,默认为false
server:port: 8081

ProviderClient 调用下游服务的Client

@FeignClient("provider")
public interface ProviderClient {@GetMapping("/test")String test();}

SpringCloudGatewayDemoApplication gateway 和 open-feign混用会导致feign找不到converter,需要自己配置一个bean

@RestController
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
@RequiredArgsConstructor
public class SpringCloudGatewayDemoApplication {private final ProviderClient providerClient;@Bean@LoadBalancedRestTemplate getRestTemplate(){return new RestTemplate();}// https://q.cnblogs.com/q/128774/@Bean@ConditionalOnMissingBeanpublic HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));}@GetMapping("/test")public String test(){return providerClient.test();}public static void main(String[] args) {SpringApplication.run(SpringCloudGatewayDemoApplication.class, args);}}

2.2 创建工程provider

build.gradle

plugins {id 'org.springframework.boot' version '2.5.3'id 'io.spring.dependency-management' version '1.0.11.RELEASE'id 'java'
}group = 'com.individual'
version = '1.0.0-SNAPSHOT'
sourceCompatibility = '11'repositories {mavenCentral()
}ext {set('springCloudVersion', "2020.0.3")set('springCloudAlibabaVersion', "2021.1")
}dependencies {implementation 'org.springframework.boot:spring-boot-starter-data-jpa'implementation 'org.springframework.boot:spring-boot-starter-jdbc'implementation 'org.springframework.boot:spring-boot-starter-tomcat'implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j'implementation 'org.springframework.cloud:spring-cloud-starter-gateway'implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer'implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'implementation 'mysql:mysql-connector-java'compileOnly 'org.projectlombok:lombok'
//    developmentOnly 'org.springframework.boot:spring-boot-devtools'annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'annotationProcessor 'org.projectlombok:lombok'testImplementation 'org.springframework.boot:spring-boot-starter-test'testImplementation 'io.projectreactor:reactor-test'
}dependencyManagement {imports {mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}"}
}test {useJUnitPlatform()
}

bootstrap.yml

spring:application:name: provider
server:port: 8082

application.yml

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql:///otr_gateway

ProviderApplication

@Slf4j
@RestController
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {@Value("${server.port}")Integer port;@GetMapping("/test")public String test(){log.info("port is: " + port);return "load balance service port: " + port;}public static void main(String[] args) {SpringApplication.run(ProviderApplication.class, args);}}

2.3 Nacos Server Setup

下载nacos最新稳定版,解压并进入bin目录,在目录下打开shell,键入以下命令启动单点

.\startup.cmd -m standalone

在configurations中创建两个yml文件(主要是为了演示Nacos中的配置分离 shared-config

  1. spring-cloud-gateway-demo
  2. gateway-routes.yml

spring-cloud-gateway-demo

spring:  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    username: root    password: 123456    url: jdbc:mysql:///otr_gateway

gateway-routes.yml

spring:  cloud:    gateway:      routes:        - id: provider          uri: lb://provider          predicates:            - Path=/api/v1/**          filters:            - StripPrefix=2

2.4 启动工程并测试

启动gateway,同时启动两个provider(可以一个run,一个debug,也可以设置parallel run,记得换配置文件中的端口)

接下来就可以测试效果了(下面为动图演示,打不开可以在浏览器独立窗口中打开查看)

引用

《Spring Cloud Alibaba 微服务原理与实战》 谭峰·著

通过Nacos动态刷新Spring Cloud Gateway的路由

Spring Cloud Gateway reference

Nacos系列(10)-Nacos开启shared-configs配置共享,读取多个配置

WebFlux 之 Mono API 教程

一文了解 Kubernetes 中的服务发现

Nacos + Gateway 实现动态刷新路由相关推荐

  1. 基于Nacos配置中心实现Spring Cloud Gateway的动态路由管理

    前面我们了解过了Sentinel 网关流量控制之Spring Cloud Gateway实战,今天带给大家是基于Nacos配置中心实现Spring Cloud Gateway的动态路由管理. 1.为什 ...

  2. Nacos整合Gateway实现动态路由

    往期回顾 Nacos的安装与配置 Spring Cloud集成Nacos作为注册中心 LoadBalacer集成Nacos实现负载均衡 常见的负载均衡策略分析 Spring Cloud集成Dubbo实 ...

  3. Spring Cloud GateWay系列(三):路由规则动态刷新

    Spring Cloud Gateway旨在提供一种简单而有效的方式来路由API,并为它们提供横切关注点,例如:安全性.监控/指标和弹性.Route(路由)是网关的基本单元,由唯一标识符ID.目标地址 ...

  4. 基于Nacos实现Spring Cloud Gateway实现动态路由

    简介 该文档主要介绍以Nacos为配置中心,实现Spring Cloud GateWay 实现动态路由的功能.Spring Cloud Gateway启动时候,就将路由配置和规则加载到内存里,无法做到 ...

  5. SpringCloudGateway 集成 nacos 整合实现动态路由_04

    接上一篇:SpringCloud Gateway 集成 oauth2 实现统一认证授权 文章目录 一.目前存在的问题 1. 问题简述 2. 集成nacos前配置 3. 前言简述 二.网关模块改造集成n ...

  6. Spring Cloud Alibaba 集成 Gateway 实现动态路由功能

    文章目录 1 摘要 2 核心 Maven 依赖 3 名词释义 4 Gateway 动态路由原理 5 数据库表 6 核心代码 6.1 配置信息 6.2 路由实体类 6.3 本地路由数据库持久层(DAO/ ...

  7. springboot+openFeign+nacos+gateway开发实战

    前面说了openFeign整合nacos进行服务之间的调用,本文来说下springboot+openFeign+nacos+gateway开发实战.说下服务网关gateway实战相关的内容. 文章目录 ...

  8. spring-cloud(十一)GateWay强大的路由谓词(断言)功能

    spring-cloud-Hoxton.SR6 (十一)GateWay强大的路由谓词(断言)功能 本文spring-cloud 版本为:hoxton.sr6 本文spring-boot版本为:2.2. ...

  9. Spring Gateway静态文件路由

    Spring Gateway静态文件路由 Spring gateway路由简介 路由到其他微服务的API路由 Spring zuul Spring Gateway 静态文件服务 Spring zuul ...

最新文章

  1. mysql数据放在什么位置,mysql数据存放的位置在哪
  2. linkedlist(c语言_简单实现)
  3. 数据分析与挖掘实战-基于水色图像的水质评价
  4. java fileupload 文件_java用Commons fileupload 文件的上传
  5. s3k3 破旧不堪的拐杖被扔出去几米远
  6. 47 FI配置-财务会计-固定资产-一般评估-定义资产分类中的折旧范围
  7. Java并发编程系列
  8. MySQl中文1001无标题_Mysql中字段类型不一致导致索引无效的处理办法
  9. c语言趣味小程序,一个有趣的小程序
  10. CYYMysql 源码解读 3
  11. python抓取汤不热视频_你们想要的 Tumblr 爬虫
  12. sqoop 中文文档 User guide 三 export
  13. C# 文件读写系列二
  14. Xilinx Artix-7 Aurora调试过程中遇到的问题
  15. 加密与解密工具大礼包 2010年新品
  16. C++中用两个栈实现一个队列
  17. 如何将谷歌地图叠加到MapGIS三维地球场景
  18. win10计算机快捷键设置,win10计算器快捷键设置_w10电脑计算器快捷键怎么添加-win7之家...
  19. CDN是什么意思 CDN加速服务有什么功能和作用?
  20. minicom - 友好易用的串口通信程序

热门文章

  1. 【UE 材质】磨砂玻璃材质
  2. 利用迭代OTSU方法分割植物病斑
  3. thawte代码签名证书,comodo软件签名证书,symantec,digicert签名证书的区别
  4. SSM综合项目实战(TTSC) -- day02 Dubbo注册中心,通用Mapper,分页插件
  5. 正确刷新Qt表格内容
  6. android webview 清除历史,如何在android中清除webview历史记录
  7. SDF Volume
  8. 暴力破解WPA(WPA2 PSK)密码
  9. 基于hamming编译码matlab误码率仿真
  10. Unable to build Hibernate SessionFactory