ETJava Beta | Java    注册   登录
  • 搜索:
  • 线上debug&gateway自定义路由规则

    发表于      阅读(1)     博客类别:Crawler     转自:https://www.cnblogs.com/zgq7/p/18492954
    如有侵权 请联系我们删除  (页面底部联系我们)  
    1. 如何进行线上debug。
    2. 如何在gateway自定义路由规则去进行请求分发,让请求打到集群模式下我们想要的节点。
    drawing

    1.配置remote debug

    1.在启动参数配置参数:

    -Xdebug
    -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6364
    
    drawing

    2.新建remote
    drawing

    3.启动remote

    2.gateway改造

    我个人的需求是把某个用户的请求,打到我想要的节点(开启了debug模式的节点),避免因为集群节点的负载导致请求打到其他节点,也避免影响其他用户的正常请求流程。

    我的做法是拦截请求头中的Authorization=xxx进行判断,因此参考了gateway的路由策略:
    gateway 路由匹配策略

    而gateway自带的路由策略是通过regix(正则匹配)来实现的,因此我做了以下改造:

    1.新增HeaderValueRoutePredicateFactory

    public class HeaderValueRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderValueRoutePredicateFactory.Config> {
    
        private static final String KEY_1 = "headerName";
        private static final String KEY_2 = "headerValue";
    
        public HeaderValueRoutePredicateFactory() {
            super(Config.class);
        }
    
        @Override
        public List<String> shortcutFieldOrder() {
            return Arrays.asList(KEY_1, KEY_2);
        }
    
        @Override
        public Predicate<ServerWebExchange> apply(Config config) {
            return new GatewayPredicate() {
                @Override
                public boolean test(ServerWebExchange exchange) {
                    List<String> values = exchange.getRequest().getHeaders().getOrDefault(config.getHeaderName(),
                            Collections.emptyList());
                    if (values.isEmpty()) {
                        return false;
                    }
    
                    boolean match = values.stream().allMatch(item -> item.equals(config.getHeaderValue()));
                    if (match) {
                        log.info("debug模式route策略已触发");
                    }
    
                    return match;
                }
    
                @Override
                public Object getConfig() {
                    return config;
                }
    
                @Override
                public String toString() {
                    return String.format("HeaderName: %s headerValue=%s", config.getHeaderName(), config.getHeaderValue());
                }
            };
        }
    
        public static class Config {
    
            private String headerName;
    
            private String headerValue;
    
            public String getHeaderName() {
                return headerName;
            }
    
            public Config setHeaderName(String headerName) {
                this.headerName = headerName;
                return this;
            }
    
            public String getHeaderValue() {
                return headerValue;
            }
    
            public Config setHeaderValue(String headerValue) {
                this.headerValue = headerValue;
                return this;
            }
        }
    
    }
    

    代码笔记:

    • 获取系统缓存路由策略(可以看网关中配置的全部策略)
      org.springframework.cloud.gateway.route.CachingRouteLocator#getRoutes
    • 获取路由策略(根据请求条件匹配)
      org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping#getHandlerInternal
    • 获取路由策略(根据请求条件匹配)
      org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping#lookupRoute

    2.配置类

    @Configuration
    public class Config {
    
        @Bean
        public HeaderValueRoutePredicateFactory headerValueRoutePredicateFactory() {
            return new HeaderValueRoutePredicateFactory();
        }
    
    }
    

    3.修改gateway配置

    spring:
      cloud:
        gateway:
          routes:
            # 当请求路径为/ims/**会被该规则路由
            - id: ims
              uri: lb://ims
              predicates:
                - Path=/ims/**
              filters:
                - StripPrefix=1
            # 当请求头中带有Authorization=ff4a4ce5-5276-4263-b817-34d1ce553421且路径为/ims/**会被该规则路由
            - id: ims-debug
              uri: lb://ims-debug
              # 配置-1是为了让该路由策略在id: ims 前面进行判断,否则会触发id=ims的路由策略,不会触发id=ims-debug的路由策略
              order: -1
              predicates:
                - Path=/ims/**
                - HeaderValue=Authorization,ff4a4ce5-5276-4263-b817-34d1ce553421
              filters:
                - StripPrefix=1
    

    3.nacos配置

    1.正常的节点配置

    -Dspring.application.name=ims
    

    2.debug的节点配置

    -Dspring.application.name=ims-debug
    

    本质上ims和ims-debug是同一服务,只是服务名不同,区分开是为了方便路由

    4.其他问题

    1. 正常情况下,如果是生产环境,ims-debug服务即使开启了debug模式,但会因为网络问题导致办公网的本地无法进行连接。这种情况我们可以让运维申请跳板机、VPN来对接专用网络,另外debug的对外端口也要申请好。
    2. 我在网上还看到其他的线上debug方式 点击跳转他人链接,因此我这种方式未必适合所有人(但是都没有考虑集群下请求如果不进入当前节点的问题),本人只是折中。
    3. 即使你学会了也没什么用,正常情况下不会让开发者进行线上debug。作者本人也只是心血来潮。