续接上一篇gateway简单应用的基础上

1.添加actuator的依赖:


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>


2.yml文件设置:


#配置actuator 提供的端点的安全性 # 暴露端点,供web访问到配置的网关路由 management: endpoints: web: exposure: include: '*'


文件所有内容:

# gateway 网关路由的配置应用
spring:
  application:
    name: spring-cloud-gateway
  cloud:
    gateway:
      routes:
        # gateway实现负载均衡的配置方式
        - id: gateway_route
          # lb:服务头,实现负载均衡的时候都要这样写服务名,而不懈具体的IP端口,因为一个服务名下面可能有多个服务对应的端口
          uri: lb://spring-cloud-user-provider
          predicates:
            - Path=/gateway/**
          filters:
            - StripPrefix=1
        #多路由的配置
        - id: request_ratelimiter_route
          #网关映射到的路径
          uri: http://localhost:8080/
          #断言的设置,一种路由匹配规则,对请求的路径进行判断
          predicates:
            #映射路径 -> http://localhost:8088/gateway/user
            - Path=/ratelimiter/**
            # 路径参数的映射 http://localhost:8088/gateway/user?name=zhou
            - Query=name,zhou
            - Method=GET
          filters:
            # 路径过滤,去掉路径前缀参数个数 gateway:http://localhost:8088/gateway/test -> http://localhost:8088/test
            - StripPrefix=1
            - name: RequestRateLimiter  #过滤器名字
              args:  #过滤的参数设置
                keyResolver: '#{@ipAddressKeyResolver}'  #配置引入定义的限流的keyResolver
                redis-rate-limiter.replenishRate: 1   # 每秒生成的令牌桶的个数
                redis-rate-limiter.burstCapacity: 2  #令牌桶的容量
        #重试机制的过滤配置; id:路由的名称,多个路由区别名
        - id: retry_route
          predicates:
            - Path=/retry/**
          uri: http://localhost:8080/
          filters:
            - StripPrefix=1
            - name: Retry
              args:
                retries: 3 #重试的次数
                status: 503  #当服务端返回的状态码是503的时候才会触发重试
        #自定义过滤器
        - id: define_route
          predicates:
            - Path=/define/**
          uri: http://localhost:8080/
          filters:
            - StripPrefix=1
            - MyDefine=Zhou_Guanjun
      #配置服务发现(实现负载均衡时开启)
      discovery:
        locator:
          lower-case-service-id: true  #大小写敏感
          enabled: true  # 开启服务地址的发现


  # redis 主机地址的配置
  redis:
    host: 192.168.43.84
    port: 6379
    timeout: 5000
server:
  port: 8088
  #配置指定的服务注册中心,配置负载均衡的时候需要配置(从服务注册中心获取服务地址列表)
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
#配置actuator 提供的端点的安全性
# 暴露端点
management:
  endpoints:
    web:
      exposure:
        include: '*'

3.自定义实现类:使用了redis的缓存机制,实现存储动态路由网关,使用postman工具进行测试动态的网关路由的配置方式

package com.self.springcloud.springcloudgateways;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 *    自定义的动态路由的实现持久化操作;
 *    实现接口RouteDefinitionRepository
 *
 *
 */
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
    //定义路由的名字
    private final static String GATEWAY_ROTE_KEY="gateway_dynamic_route";

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 获取动态的路由
     * @return
     */
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitionList=new ArrayList<>();
        redisTemplate.opsForHash().values(GATEWAY_ROTE_KEY).stream().forEach(route->{
            routeDefinitionList.add(JSON.parseObject(route.toString(),RouteDefinition.class));
        });
        return Flux.fromIterable(routeDefinitionList);
    }

    /**
     *  保存路由的方式
     * @param route
     * @return
     */
    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        // 把routeDefinition对象转换为json字符串
        return route.flatMap(routeDefinition -> {
            redisTemplate.opsForHash().put(GATEWAY_ROTE_KEY,routeDefinition.getId(), JSON.toJSONString(routeDefinition));
            return Mono.empty();
        });
    }

    /**
     *  删除ID
     * @param routeId
     * @return
     */
    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id->{
            if (redisTemplate.opsForHash().hasKey(GATEWAY_ROTE_KEY,id)){
                redisTemplate.opsForHash().delete(GATEWAY_ROTE_KEY,id);
                return Mono.empty();
            }
            return Mono.defer(()-> Mono.error(new Exception("routeDefinition not found:"+routeId)));
        });
    }
}

 

4.测试结果:

测试用例:该代码在postman内,为json格式

{
    "uri": "https://www.baidu.com",
    "predicates": [{
        "name": "Path",
        "args": {
            "pattern": "/baidu/**"
        }
    }],
    "filters": [{
        "name": "StripPrefix",
        "args": {
            "_genkey_0":1
        }
    }]
}

springboot 路由设置 springboot自定义路由_ide

发送配置的路由数据后,需要使用refresh刷新缓存才能生效

springboot 路由设置 springboot自定义路由_spring_02

网关列表的显示:

springboot 路由设置 springboot自定义路由_ide_03

这是可以访问路由跳转百度的链接:通过自己的URL路由到百度下面

springboot 路由设置 springboot自定义路由_springboot 路由设置_04

同样路由存储到了redis里面:

springboot 路由设置 springboot自定义路由_redis_05