Nacos集成Spring Cloud Gateway实现动态路由

2年前 (2022) 程序员胖胖胖虎阿
153 0 0

Nacos集成Spring Cloud Gateway实现动态路由

前面我们已经介绍了Nacos 的安装与配置,Spring Cloud 集成Nacos 作为服务的注册中心和配置中心,集成Nacos 实现服务的负载均衡和一些常见的负载均衡策略、使用Dubbo、OpenFegin进行RPC调用以及整合Spring Cloud Gateway作为服务的网关和Gateway的过滤器配置
接下来就让我们一起来看看Spring Cloud Gateway的动态路由以及负载均衡
关联服务名的动态路由
之前我们都是这样来配置的路由

service-url:
  user-service: http://localhost:...
spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          uri: ${service-url.user-service}/user/get/{id}
          predicates:
            - Path=/user/get/{id}

复制代码
相信同学们都发现了一个问题,在微服务集群部署中一个服务可能会有多台主机,我们这样配置路由不够灵活,每更改一次服务的主机信息都要重新编写一次配制文件,然后还需要重启Gateway服务器。我们要知道,在真正的项目中重启服务是很耗时的,我们应该尽量避免这种情况
Spring Cloud Gateway提供了lb//服务名的方式来动态的配置路由,网关会根据注册中心的服务名动态的获取服务的URL,这样即便该服务的某一台主机地址改变或者挂掉,网关都不必再跟着改变
因此,我们可以将路由更改成这种方式

spring:
  cloud:
    gateway:
      routes:
        - id: path_route
          # uri: ${service-url.user-service}/user/get/{id}
          uri: lb://user-service
          predicates:
            - Path=/user/get/{id}

复制代码
注意,引入依赖时需要排除Nacos中ribbon的依赖,然后再导入loadbalancer的依赖

由于 Netflix Ribbon 进入停更维护阶段,因此 SpringCloud 2020.0.1 版本之后 删除了eureka中的ribbon,替代ribbon的是spring cloud自带的LoadBalancer,默认使用的是轮询的方式 。新版本的 Nacos discovery 都已经移除了 Ribbon ,此时我们需要引入 loadbalancer 代替,才能调用服务提供者提供的服务

       `
<dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
           <exclusions>
               <!-- 将ribbon排除 -->
               <exclusion>
                   <groupId>org.springframework.cloud</groupId>
                   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
               </exclusion>
           </exclusions>
       </dependency>

       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-loadbalancer</artifactId>
       </dependency>

复制代码
我们启动网关,和8080,8081这两个服务来进行测试,如图所示

![图片](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/454a5a0804724059ad2fb1eb45e2730a~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp)

我们再来看看Naocs的控制台

![图片](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fbdbad19bf624fb295c77d260050e617~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp)

然后访问进行测试(访问多次),观察控制台输出

![图片](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/00e7bb0afe0741bbbbf155ead4f85722~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp)


![图片](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0427ef79d41e4ee1966fb502ed86d788~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp)


![图片](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4c0228e45c564efc9dc015357ea19c69~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp)

从图中可以看到,通过lb://服务名 的方式配置该服务的各个主机都有被访问过,这是因为集成了LoadBalancer是实现了负载均衡,默认轮询
基于Nacos配置中的动态路由
前面我们做到了网关屏蔽服务的上下线的细节,但是,当我们想要对路由进行增加,或者服务全部下线删除该服务的路由的情况我们还是需要更改配制文件,然后重启网关。
所以,我们可以基于配置中心来实现路由的动态扩容,配置中心我使用的Nacos
导入对应依赖
     ```
   <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

复制代码
编写对应的配制文件
编写bootstrap.yml ,主要是对Nacos配置中心的一些设置

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.199.128:8848 #Nacos地址
      config:
        server-addr: 192.168.199.128:8848 #Nacos地址
        file-extension: yaml #这里我们获取的yaml格式的配置

复制代码
编写application.yml ,启用对应环境

server:
  port: 80
spring:
  profiles:
    active: dev

复制代码
在Nacos后台编写对应的配制文件,dataId为gateway-service-dev.yaml

spring:
  cloud:
    gateway:
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_UNIQUE
      globalcors:
        cors-configurations:
          '[/**]':
            allowedHeaders: '*'
            allowedMethods: '*'
            allowedOrigins: '*'
      routes:
        - id: path_route
          uri: lb://user-service
          predicates:
            - Path=/user/get/{id}
            
  ##################省略数据库,redis等其他配置#########################

复制代码
启动网关和user-service

Nacos集成Spring Cloud Gateway实现动态路由

添加路由
接下来我们在Nacos配置中心添加新的路由

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_UNIQUE
      globalcors:
        cors-configurations:
          '[/**]':
            allowedHeaders: '*'
            allowedMethods: '*'
            allowedOrigins: '*'
      routes:
        - id: path_route
          # uri: ${service-url.user-service}/user/get/{id}
          uri: lb://user-service
          predicates:
            - Path=/user/get/{id}
            
        - id: userservice_route
          uri: http://localhost:8080
          predicates:
            - Path=/user/test

复制代码
配置中心发布前访问http://localhost/user/test/试一试:

Nacos集成Spring Cloud Gateway实现动态路由

然后将新的配制文件发布,再访问测试

Nacos集成Spring Cloud Gateway实现动态路由

观察控制台可以看到网关服务在配置中心发布新的配置后进行了更新

Nacos集成Spring Cloud Gateway实现动态路由

关于集成Nacos实现动态路由还有另外的方式,在配置中心创建son文件,然后通过json格式来管理各个路由,这种方式我就不再演示了,感兴趣的同学可以上网自行搜索。个人认为yml的格式可读性要高一些

基于Nacos权重的负载均衡策略
使用LoadBalancer进行负载均衡前面文章已经介绍过,如果还不是很熟悉的同学请先阅读:
LoadBalacer集成Nacos实现负载均衡
常见的负载均衡策略分析
接下来我就简单的演示下基于Nacos权重的负载均衡吧

package cuit.epoch.pymjl.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

import javax.annotation.Resource;

/**
 * @author Pymjl
 * @version 1.0
 * @date 2022/9/2 15:36
 **/
@LoadBalancerClients(defaultConfiguration = NacosLoadBalancerConfig.class)
public class NacosLoadBalancerConfig {
    @Resource
    NacosDiscoveryProperties nacosDiscoveryProperties;

    @Bean
    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(
            Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new NacosLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
    }
}

复制代码
启动服务

Nacos集成Spring Cloud Gateway实现动态路由

Nacos配置中心的路由规则
spring:
cloud:

gateway:
  discovery:
    locator:
      enabled: true
  default-filters:
    - DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_UNIQUE
  globalcors:
    cors-configurations:
      '[/**]':
        allowedHeaders: '*'
        allowedMethods: '*'
        allowedOrigins: '*'
  routes:
    - id: path_route
      # uri: ${service-url.user-service}/user/get/{id}
      uri: lb://user-service
      predicates:
        - Path=/user/get/{id}
        
    - id: userservice_route
      uri: lb://user-service
      predicates:
        - Path=/user/test

复制代码
修改服务的权重

Nacos集成Spring Cloud Gateway实现动态路由

多次访问http://localhost/user/test

Nacos集成Spring Cloud Gateway实现动态路由

Nacos集成Spring Cloud Gateway实现动态路由

可以看见,访问频率大致与权重相匹配

版权声明:程序员胖胖胖虎阿 发表于 2022年9月19日 下午6:48。
转载请注明:Nacos集成Spring Cloud Gateway实现动态路由 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...