溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用hystrix的配置

發(fā)布時間:2021-10-21 17:36:46 來源:億速云 閱讀:257 作者:iii 欄目:編程語言

這篇文章主要介紹“如何使用hystrix的配置”,在日常操作中,相信很多人在如何使用hystrix的配置問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用hystrix的配置”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

前言

feign是一個出色的Http請求客戶端封裝框架,feign-hystrix是整個框架體系里的其中一個模塊,用來集成hystrix熔斷器的,feign和hystrix這兩個項目都是Netflix開源的(openfeign已獨立迭代)。在spring boot項目中,可以使用spring-cloud-starter-openfeign模塊,無縫集成feign和hystrix。但是,hystrix默認采用的Archaius來驅(qū)動hystrix的配置系統(tǒng),無縫集成的同時,也會把archaius-core給引入進來。archaius是一個配置中心項目,類似spring cloud config和apollo,如果archaius只是作為hystrix配置的驅(qū)動,項目啟動時會打印煩人的警告日志,提示你沒有配置任何動態(tài)配置源。當項目里已經(jīng)采用了apollo時,可以直接剔除掉Archaius,他們的功能定位高度重合了。直接剔除依賴,會導(dǎo)致原本配置在spring中的配置不生效,博主也是在不小心剔除后,遇到了配置不生效的問題,才有了本篇博文,記錄下過程。只要稍加改動,結(jié)合apollo配置動態(tài)下發(fā)能力,可以做到hystrix的配置實時動態(tài)生效。

  • feign:https://github.com/OpenFeign/feign

  • hystrix:https://github.com/Netflix/Hystrix

  • archaius:https://github.com/Netflix/archaius

  • apollo:https://github.com/ctripcorp/apollo

archaius警告日志

2020-12-10 11:19:41.766 WARN 12835 --- [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.
2020-12-10 11:19:41.766 INFO 12835 --- [ main] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2020-12-10 11:19:41.772 WARN 12835 --- [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.
2020-12-10 11:19:41.772 INFO 12835 --- [ main] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.

我們遇到的問題

在一次系統(tǒng)優(yōu)化重構(gòu)中,博主給整個項目來了一個360的大瘦身,把所有的未使用的依賴統(tǒng)統(tǒng)給挪走了。其中就包括了spring-cloud-starter-openfeign模塊的archaius-core依賴。因為我們已經(jīng)使用了apollo配置中心,archaius在這個項目里顯得很多余,而且還會打印煩人的警告日志。所以就直接排除了,如:

implementation ('org.springframework.cloud:spring-cloud-starter-openfeign'){
    exclude(module:"archaius-core")
}

為此,專門了解了下archaius的來歷,并且針對feign的熔斷器的Fallback能力進行了測試,一切運行正常。上線一周后,問題暴露出來了,同事反饋,hystrix的配置好像不生效了?,F(xiàn)象是,原本設(shè)置的hystrix線程執(zhí)行不超時,卻發(fā)生了很多執(zhí)行一秒就超時了,我們的關(guān)鍵配置如下(這不是一個很好的配置示范,后面會調(diào)整更細粒度控制):

#禁止執(zhí)行超時
hystrix.command.default.execution.timeout.enabled = false

直觀感覺就是這個配置不生效了,聯(lián)想到archaius-core被移除,所以先立馬恢復(fù)了依賴,重新打包上線,問題解決。就這?為了徹底搞清楚Hystrix的配置加載過程,我們對feign整合hystrix進行了全面的了解。
 

hystrix在feign中的加載過程

在spring-cloud-starter-openfeign的封裝下,使用起來非常簡單,但是內(nèi)部的加載流程非常復(fù)雜。所以博主也不打算全面鋪開來說這塊內(nèi)容,有機會會獨立一篇來說。這里根據(jù)我們上文遇到的禁用執(zhí)行超時不生效的問題,博主總結(jié)了加載流程中的幾個關(guān)鍵的地方:
Feign和Hystrix的橋接器Feign-Hystrix
如何使用hystrix的配置
這個項目是feign和hystrix的橋接器,通過這樣的一個橋接器,將兩個框架的api能力整合在了一起,下面簡要闡述下,加載過程關(guān)鍵類的作用:

  • SetterFactory:承載了構(gòu)造HystrixCommand實例的所有的配置的接口,有一個默認實現(xiàn)Default,在下面會用到,是自定義配置實現(xiàn)的突破口

  • HystrixInvocationHandler:這是一個實現(xiàn)了JDK代理接口類,用來代理Feign最終的執(zhí)行,HystrixCommand類就是在這個實例里被構(gòu)造執(zhí)行的,使用的構(gòu)造方法正是帶入?yún)etter的構(gòu)造方法,集成方會實現(xiàn)SetterFactory來構(gòu)造Setter。調(diào)試程序時我們將端點打進這個類里,就可以看到配置加載的情況

如何使用hystrix的配置

spring boot自動加載hystrix

@Configuration
@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
protected static class HystrixFeignConfiguration {

   @Bean
   @Scope("prototype")
   @ConditionalOnMissingBean
   @ConditionalOnProperty(name = "feign.hystrix.enabled")
   public Feign.Builder feignHystrixBuilder() {
      return HystrixFeign.builder();
   }
}

這里是Hystrix在feign框架下加載的總?cè)肟?。這個默認的構(gòu)建器Builder中,有一個默認實現(xiàn)的SetterFactory,這個SetterFactory專門負責(zé)傳遞參數(shù)給Hystrix初始化HystrixCommand用。可以看到這里Bean的實例化加上了@ConditionalOnMissingBean條件約束,既我們可以自定義實現(xiàn)Hystrix的構(gòu)造器,覆蓋這里的實現(xiàn),在自定義的構(gòu)造器中,可以通過自定義實現(xiàn)SetterFactory,來注入任意的配置。這個是實現(xiàn)Hystrix配置自定義加載的方式之一,不過不推薦,沒必要破壞spirng現(xiàn)有的這種結(jié)構(gòu),而且代碼也會比較冗長(下面{...}省略了一百多行配置處理代碼,用來兼容Hystrix現(xiàn)有配置定義),看起來如下:
如何使用hystrix的配置
 

Hystrix的動態(tài)兜底配置

配置是hystrix的核心,各種策略的選擇執(zhí)行都需要配置來驅(qū)動,所以,雖然在應(yīng)用層面不需要太多的配置設(shè)置,但是必要的配置hystrix都會填充一個默認值,比如,hystrix默認執(zhí)行超時設(shè)置的1s。Hystrix中的配置有三個層次的加載優(yōu)先級,如:

  1. 最先加載Setter:Setter是用戶傳遞給Hystrix構(gòu)造器的,所以優(yōu)先級別最高

  2. 其次加載動態(tài)配置源:如果必要的配置在Setter里沒有找到,則在動態(tài)配置源中獲取

  3. 最后加載默認配置:如果動態(tài)配置源中也沒有找到配置,則采用默認的配置

其中動態(tài)配置源,有一個基于SystemProperties的配置實現(xiàn)HystrixDynamicPropertiesSystemProperties。HystrixCommand在實例化時,如果用戶沒有給到具體的配置,Hystrix每次都會去SystemProperties中尋找配置。也就是說,我們可以通過-D參數(shù)注入任意Hystrix的配置參數(shù),都會生效。有了這個特性,可以非常簡單的結(jié)合apollo,達到hystrix配置動態(tài)生效的效果,而且所有配置兼容Hystrix原本的配置。
 

apollo配置驅(qū)動Hystrix

實現(xiàn)這個功能的關(guān)鍵是。系統(tǒng)初始化時,將hystrix.command前綴相關(guān)的配置從apollo中獲取到然后統(tǒng)統(tǒng)注入SystemProperties。配置更新時,同時更新SystemProperties中的配置即可,非常簡單,用代碼說話:

/**
 * @author kl (http://kailing.pub)
 * @since 2020/12/10
 */
@Slf4j
@Configuration
@AutoConfigureBefore(value = {FeignClientsConfiguration.class, FeignAutoConfiguration.class})
public class HystrixConfiguration{

    public static final String DYNAMIC_TAG = "dynamic.";
    public static final String DYNAMIC_PREFIX = DYNAMIC_TAG + "hystrix.command.";
    public static final String PREFIX = "hystrix.command.";

    @ApolloConfig
    private Config config;

    @PostConstruct
    public void initHystrix(){
        this.config.addChangeListener(
                event -> this.loadHystrixConfig(event.changedKeys()),
                null,
                Sets.newHashSet(DYNAMIC_PREFIX)
        );
        this.loadHystrixConfig(config.getPropertyNames());
    }

    private void loadHystrixConfig(Setconfigkyes) {
        configkyes.forEach(key -> {
            if (StringUtils.containsIgnoreCase(key, PREFIX)) {
                String value = config.getProperty(key, null);
                String realKey = key.replaceAll(DYNAMIC_TAG,"").trim();
                System.setProperty(realKey, value);
                log.info("Hystrix config: {}={}", key, value);
            }
        });
    }

}

這里注意一個問題:為啥這里多設(shè)計了一個dynamic.前綴的配置,這是因為博主在測試過程中觸發(fā)了apollo配置監(jiān)聽器隱藏的問題,導(dǎo)致Apollo的動態(tài)監(jiān)聽器不生效了。Apollo配置加載是以SystemProperties為最高優(yōu)先級的,當配置發(fā)生變化時,apollo會將SystemProperties覆蓋到配置之后,才比較本次配置發(fā)布是否有更新。因為我們一開始就將相關(guān)的配置加載到SystemProperties里了,所以每次變更都會被覆蓋成之前的值,導(dǎo)致更新判斷失效,一直進不了監(jiān)聽器。如果想要動態(tài)更新,就需要維護一份apollo的配置和SystemProperties里的映射關(guān)系,而不能保持一致,這樣每次修改apollo時,就可以將維護映射關(guān)系的前綴去掉,然后將值動態(tài)更新到SystemProperties。目前的設(shè)計里,既支持原生的所有配置一次性加載,也支持dynamic.前綴拼裝原有配置動態(tài)加載
配置示例

#初始化時一次性加載
hystrix.command.default.execution.timeout.enabled = true
#每次修改動態(tài)生效
dynamic.hystrix.command.default.execution.timeout.enabled = true

到此,關(guān)于“如何使用hystrix的配置”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI