spring-cloud-gateway 2.2.2.RELEASE遇到一个很奇怪的问题,配置中配置的是
- id: uc-service_router
uri: lb://ucenter # 转发到用户中心
predicates:
- Path=/uc/**
而且nacos中有2个可用的ucenter服务,但是就是直转发到一台上,最后发现是配置的一个filter搞的鬼,因为跨域问题,我配置了一个这样的filter:
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
/**
* 跨域请求头重复处理过滤器
*/
@Component("corsResponseHeaderFilter")
public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
// 指定此过滤器位于NettyWriteResponseFilter之后
// 即待处理完响应体后接着处理响应头
//使用此order会导致gateway内置的lb协议不起作用,无法负载均衡,将order级别调低解决
//return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
return Ordered.LOWEST_PRECEDENCE;
}
@Override
@SuppressWarnings("serial")
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.defer(() -> {
exchange.getResponse().getHeaders().entrySet().stream()
.filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
.filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
|| kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
.forEach(kv ->
{
kv.setValue(new ArrayList<String>() {{
add(kv.getValue().get(0));
}});
});
return chain.filter(exchange);
}));
}
}
使用NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1这个顺序会使负载均衡失效,最后我把它的order顺序改为Ordered.LOWEST_PRECEDENCE,负载均衡就正常了。