• gateway的GlobalFilter调用feign后,发现GlobalFilter不起作用


    gateway的GlobalFilter调用feign后,发现GlobalFilter不起作用

    springcloud的版本为2020.0.6

    1.问题:只有feignclient无法引用

    实测发现:gateway项目可以引用其他的bean,但唯独feignclient的bean无法引用。甚至都无法让feignclient的类成为bean,一旦成为bean,那么gateway的GlobalFilter就失效,而且是所有的GlobalFilter都失效。
    但是可以引入其他类型的bean。

    2.为什么?

    不知道暂时。

    3.怎么办?

    3.1 第一种方案: 扔掉feign,采用 自带的WebClient远程调用:
    先注册一个WebClient的bean.

        @Bean
        @LoadBalanced     // 如果不添加,无法通过服务名进行调用,只能通过ip调用
        public WebClient.Builder webBuilder(){
            return WebClient.builder();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在GlobalFilter里使用

        @Autowired
        WebClient.Builder webBuilder;
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            //...
            //...
            String uri= "/getUserByToken";
            Mono<User> userMono = webBuilder.baseUrl("http://localhost:8080")
                    .build().get()
                    .uri(uri).retrieve().bodyToMono(User.class);
            User user = userMono.block();
            //...
            //...
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    但是在“User user = userMono.block();”这里面报错了,报的什么

    java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking

    说是在GlobalFilter里面不支持同步阻塞调用。FUCK!

    没有办法,只能采取异步的调用了。但这种所谓的异步,依然是隐式阻塞.不过这个倒是可行的。

        @Autowired
        WebClient.Builder webBuilder;
        //添加个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            //...
            //...
            Future<User> submit = executorService.submit(() -> {
                Mono<User> userMono = webBuilder.baseUrl("http://localhost:8080")
                        .build().get()
                        .uri(uri).retrieve().bodyToMono(User.class);
                User block = userMono.block();
                return block;
            });
            User User = submit.get();
            //...
            //...
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3.2 第二种方案:
    尽量在设计的时候在gateway里面摒弃remote-feign调用,某些操作可以直接调用service就直接调用service,比如说调用RedisService.

  • 相关阅读:
    详解Eureka的自我保护机制
    bwapp下载安装
    5-3 批处理作业调度(回溯)
    iOS查看汇编代码
    nlp序列完全可以模拟人脑智能
    C++广搜例题代码加讲解(1)
    php获取今天凌晨零点的时间
    VSCode远程连接服务器报错:Could not establish connection to “xxxxxx”的可能错误原因及解决
    进阶 | 数据科学家提高效率的 40 个 Python 技巧
    谣言检测(RDCL)——《Towards Robust False Information Detection on Social Networks with Contrastive Learning》
  • 原文地址:https://blog.csdn.net/dmw412724/article/details/126510888