从spring cloud gateway调用微服务

Posted

技术标签:

【中文标题】从spring cloud gateway调用微服务【英文标题】:Calling micro service from spring cloud gateway 【发布时间】:2021-10-23 19:26:13 【问题描述】:

在spring cloud gateway中,添加了一个过滤器,用于检查身份验证和授权以进一步处理请求。我正在使用 feign 客户端调用身份验证服务,但是通过 spring 云网关调用我的服务时出现以下错误。

java.lang.IllegalStateException: block()/blockFirst()/blockLast() 是阻塞的,线程 reactor-http-epoll-3\n\tat reactor.core.publisher.BlockingSingleSubscriber.blockingGet( BlockingSingleSubscriber.java:83)\n\tSuppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: \n在以下站点观察到错误:\n\t|_ checkpoint ⇢ org.springframework.cloud.gateway。 filter.WeightCalculatorWebFilter ....."

我想知道我使用的架构是否错误。如何进行?我被这个错误困住了。

@Autowired
private AuthenticationService authService;

// route validator
@Autowired
private RouterValidator routerValidator;

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) 
     ServerHttpRequest request = exchange.getRequest();
     if (routerValidator.isSecured.test(request)) 
         log.info("Accessing the restricted path");
         if (this.isAuthMissing(request))
             return this.onError(exchange, "Authorization header is missing in request", HttpStatus.UNAUTHORIZED);
         
         final String token = this.getAuthHeader(request);
         log.info("before authservice call");
         AuthenticationResponse user = authService.isTokenValid(token);
         log.info("after authservice call");
         if (!user.isValid())
             return this.onError(exchange, "Authorization header is invalid", HttpStatus.UNAUTHORIZED);
         log.info("before calling populatedRequest");
         this.populateRequestWithHeaders(exchange, user);
     
     return chain.filter(exchange);

private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) 
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(httpStatus);
    return response.setComplete();


private String getAuthHeader(ServerHttpRequest request) 
    return request.getHeaders().getOrEmpty("Authorization").get(0);


private boolean isAuthMissing(ServerHttpRequest request) 
    log.info("inside auth missing");
    return !request.getHeaders().containsKey("Authorization");


private void populateRequestWithHeaders(ServerWebExchange exchange, AuthenticationResponse authRes) 
    log.info("About to mutate the request->",exchange);
    exchange.getRequest().mutate()
            .header("id",Integer.toString(authRes.getUserId()))
            .build();

假装界面

@Autowired
private AuthenticationFeign auth;

public AuthenticationResponse isTokenValid(String token) 
    return auth.getValidity(token);

【问题讨论】:

feign 被阻塞,不推荐在网关中使用 @spencergibb 谢谢我现在对 webclient 做同样的事情。 【参考方案1】:

我看不清楚。但问题是:您不能在过滤器管道中进行阻塞调用。当前的反应式 impl。就是这样。如果你愿意,你可以使用 WebClient 的 .then() 方法。你应该使用网络客户端。因为它是反应性的。

此链接可能对您有所帮助: https://github.com/spring-cloud/spring-cloud-gateway/issues/980

有很长一段时间,但我想给出答案。我希望,这对你有帮助,请回复,它是否有效。

【讨论】:

以上是关于从spring cloud gateway调用微服务的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud 7:Gateway

前后端分离项目,引入 Spring Cloud Gateway 遇到的一个问题!

调用spring oauth2授权服务器时Spring Cloud Gateway卡住

服务治理:Spring Cloud Eureka

服务治理:Spring Cloud Eureka

用于复合 API 调用的 Spring Cloud Gateway?