日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Cloud Zuul的fallback优化

發布時間:2024/7/5 javascript 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Cloud Zuul的fallback优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如何在Zuul中使用fallback功能

我們在項目中使用Spring cloud zuul的時候,有一種這樣的需求,就是當我們的zuul進行路由分發時,如果后端服務沒有啟動,或者調用超時,這時候我們希望Zuul提供一種降級功能,而不是將異常暴露出來。

在Dalston版本中,Spring cloud zuul提供這種降級功能,操作步驟如下:

  • 在主函數上添加@EnbaleZuulProxy注解。
  • 實現ZuulFallbackProvider接口。

對應ZuulFallbackProvider源碼如下:

public interface ZuulFallbackProvider {

/**
* The route this fallback will be used for.
* @return The route the fallback will be used for.
*/
public String getRoute();

/**
* Provides a fallback response.
* @return The fallback response.
*/
public ClientHttpResponse fallbackResponse();
}

我們只要實現該接口,并實現public ClientHttpResponse fallbackResponse();方法,也就是說該方法會讓我定義一個ClientHttpResponse作為當異常出現時的返回內容。

通過源碼我們可知,Zuul提供三個配置文件,每一個配置文件代表用不同種方式進行請求的轉發:

  • RestClientRibbonConfiguration
  • OkHttpRibbonConfiguration
  • HttpClientRibbonConfiguration(默認情況)

HttpClientRibbonConfiguration源碼如下(只體現涉及fallback模塊):

@Configuration
@ConditionalOnRibbonHttpClient
protected static class HttpClientRibbonConfiguration {

@Autowired(required = false)
private Set<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
@Bean
@ConditionalOnMissingBean
public RibbonCommandFactory<?> ribbonCommandFactory(
SpringClientFactory clientFactory, ZuulProperties zuulProperties
)
{
return new HttpClientRibbonCommandFactory(
clientFactory,
zuulProperties,
zuulFallbackProviders
);
}
}

通過源碼我們可以了解,Zuul將你自定義的fallbackprovider保存在一個Set集合中,并作為HttpClientRibbonCommandFactory構造器的參數。
當zuul在轉發請求時最終會利用AbstractRibbonCommand進行處理。通過源碼我們知道AbstractRibbonCommand繼承了HystrixCommand,所以真正轉發請求的業務邏輯是在重寫HystrixCommand類的run方法中進行的。

具體源碼如下:

@Override
protected ClientHttpResponse run() throws Exception {
final RequestContext context = RequestContext.getCurrentContext();

RQ request = createRequest();
RS response = this.client.executeWithLoadBalancer(request, config);

context.set("ribbonResponse", response);

// Explicitly close the HttpResponse if the Hystrix command timed out to
// release the underlying HTTP connection held by the response.
//
if (this.isResponseTimedOut()) {
if (response != null) {
response.close();
}
}

return new RibbonHttpResponse(response);
}

我們知道HystrixCommand提供getFallback()方法,這個方法的作用是當run()方法執行出現異常時,會自動調用getFallback()方法,從而完成降級功能。(HystrixCommand是Hystrix的知識,有興趣的同學可以參照官方git文檔)。

由于AbstractRibbonCommand繼承了HystrixCommand,它不僅重寫了run()方法,而且重寫了getFallback()方法,具體源碼如下:

@Override
protected ClientHttpResponse getFallback() {
if(zuulFallbackProvider != null) {
return zuulFallbackProvider.fallbackResponse();
}
return super.getFallback();
}

通過源碼我們知道,首先會去判斷是否存在自定義的zuulFallbackProvider,如果有,那么直接回調你自定義實現類的fallbackResponse()方法。如果不存在會走hystrix的fallback邏輯(有可能直接拋出異常)。

說到這里Zuul的降級原理大致就說完了,細心的朋友可以發現這樣的一個問題,就是雖然Zuul提供了降級的回調方法fallbackResponse(),但是這個方法是無參的,也就是說此時雖然你能夠給調用端返回一個消息,但是此時你并不知道發生了什么樣的異常(也就是說在這里你是獲取不到異常信息的)。

Edgware.RC1版本的改進

在Edgware.RC1版本中Spring cloud zuul針對于降級進行了升級,升級的內容主要是解決上面說到的當降級出現時,怎樣在降級方法中獲取具體的異常信息。

增加了一個接口FallbackProvider,這個接口繼承了現有的ZuulFallbackProvider接口,源碼如下:

public interface FallbackProvider extends ZuulFallbackProvider {
/**
* Provides a fallback response based on the cause of the failed execution.
*
* @param cause cause of the main method failure
* @return the fallback response
*/
ClientHttpResponse fallbackResponse(Throwable cause);

}

可以看到這個接口有一個方法,這個方法的參數是Throwable,也就是說此時是用能力獲取異常信息的。

接下來改造的內容在AbstractRibbonCommand類中,主要是對原有的getFallback()進行改造,同時增加了一個getFallbackResponse()方法。下面通過源碼具體了解下:

@Override
protected ClientHttpResponse getFallback() {
if(zuulFallbackProvider != null) {
return getFallbackResponse();
}
return super.getFallback();
}

可以看到從原來調用zuulFallbackProvider.fallbackResponse();轉而調用內部方法getFallbackResponse()。

getFallbackResponse()源碼如下:

protected ClientHttpResponse getFallbackResponse() {
if (zuulFallbackProvider instanceof FallbackProvider) {
Throwable cause = getFailedExecutionException();
cause = cause == null ? getExecutionException() : cause;
if (cause == null) {
zuulFallbackProvider.fallbackResponse();
} else {
return ((FallbackProvider) zuulFallbackProvider).fallbackResponse(cause);
}
}
return zuulFallbackProvider.fallbackResponse();
}

通過源碼可知,此時會根據Throwable是否存在來決定走哪種類型的降級方法(原來的還是帶有參數的)。

到此Zuul的實現降級的原理以及Edgware.RC1中的改進就介紹完了。


總結

以上是生活随笔為你收集整理的Spring Cloud Zuul的fallback优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。