开发者

spring cloud gateway如何获取请求的真实地址

开发者 https://www.devze.com 2023-05-06 10:40 出处:网络 作者: 一只猪啊啊
目录spring cloud gateway获取请求的真实地址以下是解决办法spring cloud的GateWay网关中如何debug得到真实的路由地址总结spring cloudjs gateway获取请求的真实地址
目录
  • spring cloud gateway获取请求的真实地址
    • 以下是解决办法
  • spring cloud的GateWay网关中如何debug得到真实的路由地址
    • 总结

      spring cloudjs gateway获取请求的真实地址

      在使用spring cloud gateway的时候,路由一般配置为服务名

      例如 lb://BASE-API-WEB/xxx/bbb 路径,我们无从知道,他真正路由到什么地方去了。

      经过查看源码我发现了,

      org.springframework.cloud.gateway.filter.LoadBalancerCli开发者_JAVA学习entFilter

      这个filter中 对lb请求进行了处理,转换成真正的url地址。

      核心方法如下

       public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
             //lb下的url
       URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
              String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
              if (url == null || !"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix)) {
                  return chain.filter(exchange);
              } else {
                  ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
                  log.trace("LoadBalancerClientFilter url before: " + url);
                  ServiceInstance instance = this.loadBalancer.choose(url.getHost());
                  if (instance == null) {
                      throw new NotFoundException("Unable to find instance for " + url.getHost());
                  } else {
                      URI uri = exchange.getRequest().getURI();
                      String overrideScheme = null;
                      if (schemePrefix != null) {
                          overrideScheme = url.getScheme();
                      }
                      //真实的url
                      URI requestUrl = this.loadBalancer.reconstructURI(new LoadBalancerClientFilter.DelegatingServiceInstance(instance, overrideScheme), uri);
                      log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
                      exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
                      return chain.filter(exchange);
                  }
              }
          }

      其实,spring cloud gateway 已经打印了日志,但是默认的他是trace级别的,我们常用的日志级别是info级别,所有他不会打印,这就导致了我们在日志中看不到真实的url地址

      以下是解决办法

      1.在配置文件中设置org.springframework.cloud.gateway.filter.LoadBalancerClientFilter的日志级别

      logging.level.org.springframework.cloud.gateway.filter.LoadBalancerClientFilter=TRACE

      注意 这里的配置一定要在

      logging.level.org.springframework之后配置 不然会覆盖

      2.重写LoadBalancerClientFiltehttp://www.devze.comr 建立org.springframework.cloud.gateway.filter包 将 类重写 spingboot默认会从本项目中加载类,原先的类就被弃用了。

      3.继承LoadBalancerClientFilter 重写filter方法,将日志级别改为info编程客栈即可

        @Override
          public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
              URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
              String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
              if (url == null || !"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix)) {
                  return chain.filter(exchange);
              } else {
                  ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
                  Serhttp://www.devze.comviceInstance instance = this.loadBalancer.choose(url.getHost());
                  if (instance == null) {
                      throw new NotFoundException("Unable to find instance for " + url.getHost());
                  } else {
                      URI uri = exchange.getRequest().getURI();
                      String overrideScheme = null;
                      if (schemePrefix != null) {
                          overrideScheme = url.getScheme();
                      }
                      URI requestUrl = this.loadBalancer.reconstructURI(new LoadBalancerClientFilterBean.DelegatingServiceInstance(instance, overrideScheme), uri);
                      logger.info("becnbRAqfore url = {} , url chosen = {} " ,url, requestUrl);
                      exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
                      return chain.filter(exchange);
                  }
              }
          }

      最终效果如下 :

      spring cloud gateway如何获取请求的真实地址

      spring cloud的GateWay网关中如何debug得到真实的路由地址

      org.springframework.cloud.gateway.filter下面的

      spring cloud gateway如何获取请求的真实地址

      spring cloud gateway如何获取请求的真实地址

      然后按下 Step over 就得到了 mergedUrl 这个变量,然后就可以看到真实请求的地址了

      spring cloud gateway如何获取请求的真实地址

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号