private Integer connectTimeout; private Duration responseTimeout;2、GatewayAutoConfiguration配置类当用户没有配置httpclient,gatewayHttpClient方法会用HttpClientProperties 配置httpclient对象,配置httpclient的tcp默认的connectTimeout。
其中还会根据HttpClientProperties 配置 最大的响应头、Proxy、ssl、ConnectionProvider
@Bean
@ConditionalOnMissingBean
public HttpClient gatewayHttpClient(HttpClientProperties properties,
List customizers) {
3、NettyRoutingFilter 负责路由的服务调用,此类中根据路由配置设置远程调用的一些参数。
getHttpClient方法会尝试 从路由信息中获取connect-timeout,如果存在则设置tcp 的connectTimeout参数。
getResponseTimeout方法 会尝试 从路由信息中获取response-timeout参数,如果存在,给http调用设置超时回调
protected HttpClient getHttpClient(Route route, ServerWebExchange exchange) {
Object connectTimeoutAttr = route.getMetadata().get(CONNECT_TIMEOUT_ATTR);
if (connectTimeoutAttr != null) {
Integer connectTimeout = getInteger(connectTimeoutAttr);
return this.httpClient.tcpConfiguration((tcpClient) -> tcpClient
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout));
}
return httpClient;
}
private Duration getResponseTimeout(Route route) {
Object responseTimeoutAttr = route.getMetadata().get(RESPONSE_TIMEOUT_ATTR);
Long responseTimeout = null;
if (responseTimeoutAttr != null) {
if (responseTimeoutAttr instanceof Number) {
responseTimeout = ((Number) responseTimeoutAttr).longValue();
}
else {
responseTimeout = Long.valueOf(responseTimeoutAttr.toString());
}
}
return responseTimeout != null ? Duration.ofMillis(responseTimeout)
: properties.getResponseTimeout();
}
{
Duration responseTimeout = getResponseTimeout(route);
if (responseTimeout != null) {
responseFlux = responseFlux
.timeout(responseTimeout, Mono.error(new TimeoutException(
"Response took longer than timeout: " + responseTimeout)))
.onErrorMap(TimeoutException.class,
th -> new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT,
th.getMessage(), th));
}
}
4、参数配置spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
httpclient:
connect-timeout: 1
response-timeout: 1S
routes:
- id: yoci-api
# uri: lb://yoci-api # 动态路由方式需要配合eureka、nacos注册中心使用
uri: http://localhost:8082
predicates:
- Path=/api/**
filters:
- StripPrefix=1
metadata:
connect-timeout: 10
#单位毫秒
response-timeout: 10000
- id: autho2-server
# uri: lb://yoci-auth # 动态路由方式需要配合eureka、nacos注册中心使用
uri: http://localhost:8081
predicates:
- Path=/auth/**
filters:
5、filter 链
1、RemoveCachedBodyFilter
请求处理完后,释放缓存的 cachedRequestBody
2、AdaptCachedBodyGlobalFilter
缓存的 cachedRequestBody
3、NettyWriteResponseFilter
1、 过滤器链处理出现异常,释放下游服务的请求链接
2、请求会正常,从ServerWebExchange,获取下游服务的请求链接connection和 当前请求的response。从下游服务的链接中接收下游服务响应数据。并且根据响应头,将数据返回分为流式数据和非流式数据。流式通过connection .inbound() .receive() .retain() .map(byteBuf -> wrap(byteBuf, response)); 不停的产生数据给client
4、ForwardPathFilter
从路由信息中获取路由地址,如果不是以forward开头,则直接放过。否则 修改当前请求的地址为 路由forward地址
5、RewritePathGatewayFilterFactory
获取请求url 放入gatewayOriginalRequestUrl 变量中, 根据配置,修改请求的path,
例如 /apiserver/helloadmin to /helloadmin
6、RouteToRequestUrlFilter
获取路由信息,获取lb 的服务名,请求的path,重新构建请求path
gatewayRequestUrl lb://apiserver/helloadmin
7、LoadBalancerClientFilter
如果gatewayRequestUrl 请求的地址 的schemePrefix 是lb ,则
通过LoadBalancerClien和 lb://apiserver/helloadmin的host从注册中心获取一个可用的ServiceInstance,并且lb://apiserver 替换为 实例的协议、ip、port ,构建新的请求路径,
将原有的路径添加到gatewayOriginalRequestUrl中,将新路径添加到gatewayRequestUrl属性中。8、WebsocketRoutingFilter
如果是websocket请求,拦截,协议升级,走websocket 逻辑WebSocketService
9、NettyRoutingFilter(只处理http 和https)
获取gatewayRequestUrl 属性中此时真正要访问的路径,以及当前请求的httpMethod、headers、body为发起请求做准备。
1、根据路由信息中的metadata中的connect-timeout信息配置httpclient的tcp
2、 设置请求头和请求方法、路径,并发送请求
3、响应处理。cliRes 和 connection 设置到ServerWebExchange的gatewayClientResponse、gatewayClientResponseConnection 属性中。并获取cliRes的响应头和响应码,设置到ServerWebExchange中的response对象中。connection 将在NettyWriteResponseFilter 中使用,往调用发写数据。4、根据route中的metadata中的response-timeout信息和 HttpClientProperties中的responseTimeout,设置超时监控。优先级 route > HttpClientProperties。如果都没有配置超时时间,则不设置超时回调。
10、ForwardRoutingFilter如果是转发路径 forward:// 则调用DispatcherHandler 进行服务转发



