• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

SpringCloud Gateway 4动态路由

武飞扬头像
再见丶孙悟空
帮助1

       

        配置网关路由一般有两种方式

        application.yml 中配置

  1.  
    routes:
  2.  
    #路径匹配
  3.  
    - id: demo-server
  4.  
    uri: lb://demo-server
  5.  
    predicates:
  6.  
    # 这样写方便后面理解
  7.  
    - name: Path
  8.  
    args:
  9.  
    pattern: /api/hi/**
  10.  
    filters:
  11.  
    - name: RewritePath
  12.  
    args:
  13.  
    regexp: /api/(?<segment>.*)
  14.  
    replacement: /$\{segment}
  15.  
    - AddRequestHeader=X-Request-Foo, Bar
学新通

         代码里配置

  1.  
    @Bean
  2.  
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
  3.  
    return builder.routes()
  4.  
    .route("path_route", r -> r.path("/get")
  5.  
    .uri("http://httpbin.org"))
  6.  
    .route("host_route", r -> r.host("*.myhost.org")
  7.  
    .uri("http://httpbin.org"))
  8.  
    .route("rewrite_route", r -> r.host("*.rewrite.org")
  9.  
    .filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/${segment}"))
  10.  
    .uri("http://httpbin.org"))
  11.  
    .route("hystrix_route", r -> r.host("*.hystrix.org")
  12.  
    .filters(f -> f.hystrix(c -> c.setName("slowcmd")))
  13.  
    .uri("http://httpbin.org"))
  14.  
    .route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org")
  15.  
    .filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback")))
  16.  
    .uri("http://httpbin.org"))
  17.  
    .route("limit_route", r -> r
  18.  
    .host("*.limited.org").and().path("/anything/**")
  19.  
    .filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
  20.  
    .uri("http://httpbin.org"))
  21.  
    .build();
  22.  
    }
学新通

         无论是yml还是代码,这些配置最终都是被封装到 RouteDefinition 对象中。

        我们找到关键类 RouteDefinitionRepository,默认用InMemoryRouteDefinitionRepository。而做动态路由的关键就在这里。

  1.  
    @Component
  2.  
    public class DynamicRouteDefinitionRepository implements RouteDefinitionRepository, ApplicationEventPublisherAware {
  3.  
     
  4.  
    @Autowired
  5.  
    private GatewayRouteService gatewayRouteService;
  6.  
     
  7.  
    private ApplicationEventPublisher eventPublisher;
  8.  
     
  9.  
    private Map<String, RouteDefinition> cache = new ConcurrentHashMap<>();
  10.  
     
  11.  
    @Override
  12.  
    public Flux<RouteDefinition> getRouteDefinitions() {
  13.  
    return Flux.fromIterable(cache.values());
  14.  
    }
  15.  
     
  16.  
    @Override
  17.  
    public Mono<Void> save(Mono<RouteDefinition> route) {
  18.  
    return route.flatMap(
  19.  
    routeDefinition -> {
  20.  
    gatewayRouteService.save(RouteDefinitionConverter.convertToDTO(routeDefinition));
  21.  
    this.addCache(routeDefinition);
  22.  
    return Mono.empty();
  23.  
    });
  24.  
    }
  25.  
     
  26.  
    @Override
  27.  
    public Mono<Void> delete(Mono<String> routeId) {
  28.  
    return routeId.flatMap(
  29.  
    id -> {
  30.  
    gatewayRouteService.remove(id);
  31.  
    this.removeCache(id);
  32.  
    return Mono.empty();
  33.  
    });
  34.  
    }
  35.  
     
  36.  
    @Override
  37.  
    public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
  38.  
    this.eventPublisher = eventPublisher;
  39.  
    }
  40.  
     
  41.  
    /**
  42.  
    * 将指定路由加入到缓存中。
  43.  
    */
  44.  
    public void addCache(RouteDefinition route) {
  45.  
    this.cache.putIfAbsent(route.getId(), route);
  46.  
    this.publishEvent();
  47.  
    }
  48.  
     
  49.  
    /**
  50.  
    * 将指定路由从缓存中删除。
  51.  
    */
  52.  
    public void removeCache(String routeId) {
  53.  
    if (this.cache.remove(routeId) != null) {
  54.  
    this.publishEvent();
  55.  
    }
  56.  
    }
  57.  
     
  58.  
    public void publishEvent() {
  59.  
    eventPublisher.publishEvent(new RefreshRoutesEvent(this));
  60.  
    }
  61.  
     
  62.  
    public Map<String, RouteDefinition> getCache() {
  63.  
    return cache;
  64.  
    }
  65.  
     
  66.  
    public void setCache(Map<String, RouteDefinition> cache) {
  67.  
    this.cache = cache;
  68.  
    }
  69.  
     
  70.  
    public void clearCache() {
  71.  
    this.cache.clear();
  72.  
    }
  73.  
     
  74.  
     
  75.  
    }
学新通

解释一下这边实现的几个关键方法

  • getRouteDefinitions
    • 用于返回自定义的路由配置信息,可以从数据库或者缓存中取,自行实现
  • save
    • 用于通过 RESTFul API 新增路由信息
    • 需要开启 actuator 的 gateway 端点
  • delete
    • 用于通过 RESTFul API 删除路由信息
    • 需要开启 actuator 的 gateway 端点

我这边采用 mysql 来存储配置路由信息,表结构如下

  1.  
    SET NAMES utf8mb4;
  2.  
    SET FOREIGN_KEY_CHECKS = 0;
  3.  
     
  4.  
    -- ----------------------------
  5.  
    -- Table structure for gateway_route
  6.  
    -- ----------------------------
  7.  
    DROP TABLE IF EXISTS `gateway_route`;
  8.  
    CREATE TABLE `gateway_route` (
  9.  
    `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键',
  10.  
    `route_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '路由id',
  11.  
    `route_order` int(0) NULL DEFAULT 0 COMMENT '路由顺序',
  12.  
    `uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '路由路径',
  13.  
    `is_enable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'Y' COMMENT '是否启用',
  14.  
    `create_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建用户',
  15.  
    `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  16.  
    `update_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新用户',
  17.  
    `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  18.  
    `is_delete` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N' COMMENT '是否删除',
  19.  
    PRIMARY KEY (`id`) USING BTREE
  20.  
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '网关-路由' ROW_FORMAT = Dynamic;
  21.  
     
  22.  
    -- ----------------------------
  23.  
    -- Records of gateway_route
  24.  
    -- ----------------------------
  25.  
    INSERT INTO `gateway_route` VALUES (1, 'demo-server', 0, 'lb://demo-server', 'Y', 'admin', '2022-01-26 17:23:42', NULL, NULL, 'N');
  26.  
     
  27.  
    -- ----------------------------
  28.  
    -- Table structure for gateway_route_param
  29.  
    -- ----------------------------
  30.  
    DROP TABLE IF EXISTS `gateway_route_param`;
  31.  
    CREATE TABLE `gateway_route_param` (
  32.  
    `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键',
  33.  
    `route_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '路由id',
  34.  
    `param_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '参数名称',
  35.  
    `param_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '参数key',
  36.  
    `param_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '参数value',
  37.  
    `type` int(0) NOT NULL COMMENT '1 为predicate,2为 filter',
  38.  
    `is_enable` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'Y' COMMENT '是否生效',
  39.  
    `create_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建用户',
  40.  
    `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  41.  
    `update_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新用户',
  42.  
    `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  43.  
    `is_delete` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N' COMMENT '是否删除',
  44.  
    PRIMARY KEY (`id`) USING BTREE
  45.  
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '网关-路由参数表' ROW_FORMAT = Dynamic;
  46.  
     
  47.  
    -- ----------------------------
  48.  
    -- Records of gateway_route_param
  49.  
    -- ----------------------------
  50.  
    INSERT INTO `gateway_route_param` VALUES (1, 'demo-server', 'Path', 'pattern', '/api/hi/**', 1, 'Y', 'admin', '2022-01-26 17:26:07', 'admin', '2022-01-26 17:26:07', 'N');
  51.  
    INSERT INTO `gateway_route_param` VALUES (2, 'demo-server', 'RewritePath', 'regexp', '/api/(?<segment>.*)', 2, 'Y', 'admin', '2022-01-26 17:26:32', 'admin', '2022-01-26 17:26:32', 'N');
  52.  
    INSERT INTO `gateway_route_param` VALUES (3, 'demo-server', 'RewritePath', 'replacement', '/$\\{segment}', 2, 'Y', 'admin', '2022-02-07 11:10:53', 'admin', '2022-02-07 11:10:53', 'N');
学新通

        其中 param 中的 key,value 比较不太好理解,官方文档里也暂没有找到比较完整的示例demo。我这边通过网上资料的简单拼凑,实现了路径重写(RewritePath)的过滤器配置。

       最后贴上源代码

https://github.com/kid626/springcloud-gateway.git学新通https://github.com/kid626/springcloud-gateway.git

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggbkhb
系列文章
更多 icon
同类精品
更多 icon
继续加载