1. ribbon 快速失敗,斷路功能無法應用
這個問題無解:
網關LoadBalancerClientFilter只是使用ribbon的負載均衡策略
沒有將後續的錯誤計數應用上,導致不會將錯誤(超時,異常)的服務進行移除
https://github.com/spring-cloud/spring-cloud-gateway/issues/568
2. lb 請求默認會將服務名稱去掉
如:
http://192.168.0.100:8080/system/test ——> http://192.168.0.100:8080/test
這是因爲默認配置了 RewritePath
只要重寫過濾鏈即可,添加如下配置,覆蓋默認:
spring:
cloud:
gateway:
discovery:
filters:
- PreserveHostHeader
3. discovery.filters,default-filters區別
discovery.filters: 只有從註冊中心建立的路由的纔會附加(lb)
default-filters: 所有的路由都會增加
spring:
cloud:
gateway:
discovery:
filters:
default-filters:
4. 重試(el)配置
discovery.filters 不支持el 表達式配置。
以下配置 default-filters 正常,discovery.filters 報錯;
default-filters:
- name: Retry
args:
retries: 5
statuses:
- BAD_GATEWAY
- GATEWAY_TIMEOUT
5. 增加重試配置
通過下面的配置就可以增加重試,默認只有GET方法重試,重試3次。
只有以下異常進行重試:
IOException
org.springframework.cloud.gateway.support.TimeoutException
default-filters:
- Retry
6. gateway httpClient 連接超時控制
gateway 默認使用 netty httpClient 實現。
可以通過下面的參數進行控制;
spring:
cloud:
gateway:
httpclient:
connectTimeout: 2000
responseTimeout: 10s
注意: 如果有配置重試(retry):
connectTimeout 會進行重試
responseTimeout 不會觸發重試(可能是一種BUG),
因爲 responseTimeout 被包裝成了 ResponseStatusException ,所以沒有重試
https://github.com/spring-cloud/spring-cloud-gateway/issues/821
7. retry Hystrix 重試
retry 與 Hystrix 的順序,決定誰包含誰
Hystrix 在前:
不管重試幾次,都只會按照Hystrix超時時間爲準。
如果Hystrix超時了,也就不會重試了
retry 在前:
Hystrix超時了也會重試
通過這種關係,我們可以配置兩個 Hystrix,一個控制整個請求的時間,一個控制單次重試的時間
再單次超時時(如果有配置 responseTimeout),將異常進行轉換,達到responseTimeout也能重試的效果
配置如下:
default-filters:
- name: Hystrix
args:
name: globalcmd
fallbackUri: forward:/errorFallback
- name: Retry
args:
statuses:
- BAD_GATEWAY
- GATEWAY_TIMEOUT
- name: Hystrix
args:
name: retrycmd
fallbackUri: forward:/retryFallback
代碼:
@RequestMapping(value = "/retryFallback")
public Mono<ActionResult> retryFallback(ServerWebExchange exchange) {
Exception e = exchange.getAttribute(ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR);
if( e instanceof ResponseStatusException)
{
ResponseStatusException exception = (ResponseStatusException)e;
if(HttpStatus.GATEWAY_TIMEOUT.equals(exception.getStatus()))
{
return Mono.error(new TimeoutException(exception.getMessage()));
}
}
return Mono.error(e);
}
-------
版本:
<spring-cloud-dependencies.version>Greenwich.SR2</spring-cloud-dependencies.version> <spring-boot-dependencies.version>2.1.6.RELEASE</spring-boot-dependencies.version>