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

在Spring Cloud Gateway项目中,遇到GlobalFilter无法与FeignClient协同工作的问题。当尝试将FeignClient的bean注入到GlobalFilter时,导致GlobalFilter失效。分析原因未知,可能与Spring Cloud版本2020.0.6有关。为解决此问题,提出了两种方案:一是改用WebClient进行远程调用,但在GlobalFilter内进行同步阻塞调用会引发错误,因此采用异步调用并利用线程池来避免阻塞;二是尽量避免在Gateway中使用FeignClient,转而直接调用内部服务。这两种方案都存在一定的权衡和实施挑战。

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();
    }

在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();
        //...
        //...
    }

但是在“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();
        //...
        //...
    }

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值