您好,登錄后才能下訂單哦!
這篇文章主要介紹了hystrix配置中Apollo與Archaius有什么不同的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇hystrix配置中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.
在一次系統優化重構中,博主給整個項目來了一個360的大瘦身,把所有的未使用的依賴統統給挪走了。其中就包括了spring-cloud-starter-openfeign模塊的archaius-core依賴。因為我們已經使用了apollo配置中心,archaius在這個項目里顯得很多余,而且還會打印煩人的警告日志。所以就直接排除了,如:
implementation ('org.springframework.cloud:spring-cloud-starter-openfeign'){ exclude(module:"archaius-core") }
為此,專門了解了下archaius的來歷,并且針對feign的熔斷器的Fallback能力進行了測試,一切運行正常。上線一周后,問題暴露出來了,同事反饋,hystrix的配置好像不生效了。現象是,原本設置的hystrix線程執行不超時,卻發生了很多執行一秒就超時了,我們的關鍵配置如下(這不是一個很好的配置示范,后面會調整更細粒度控制):
#禁止執行超時 hystrix.command.default.execution.timeout.enabled = false
直觀感覺就是這個配置不生效了,聯想到archaius-core被移除,所以先立馬恢復了依賴,重新打包上線,問題解決。就這?為了徹底搞清楚Hystrix的配置加載過程,我們對feign整合hystrix進行了全面的了解。
在spring-cloud-starter-openfeign的封裝下,使用起來非常簡單,但是內部的加載流程非常復雜。所以博主也不打算全面鋪開來說這塊內容,有機會會獨立一篇來說。這里根據我們上文遇到的禁用執行超時不生效的問題,博主總結了加載流程中的幾個關鍵的地方:
Feign和Hystrix的橋接器Feign-Hystrix
這個項目是feign和hystrix的橋接器,通過這樣的一個橋接器,將兩個框架的api能力整合在了一起,下面簡要闡述下,加載過程關鍵類的作用:
SetterFactory:承載了構造HystrixCommand實例的所有的配置的接口,有一個默認實現Default,在下面會用到,是自定義配置實現的突破口
HystrixInvocationHandler:這是一個實現了JDK代理接口類,用來代理Feign最終的執行,HystrixCommand類就是在這個實例里被構造執行的,使用的構造方法正是帶入參Setter的構造方法,集成方會實現SetterFactory來構造Setter。調試程序時我們將端點打進這個類里,就可以看到配置加載的情況
@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框架下加載的總入口。這個默認的構建器Builder中,有一個默認實現的SetterFactory,這個SetterFactory專門負責傳遞參數給Hystrix初始化HystrixCommand用。可以看到這里Bean的實例化加上了@ConditionalOnMissingBean條件約束,既我們可以自定義實現Hystrix的構造器,覆蓋這里的實現,在自定義的構造器中,可以通過自定義實現SetterFactory,來注入任意的配置。這個是實現Hystrix配置自定義加載的方式之一,不過不推薦,沒必要破壞spirng現有的這種結構,而且代碼也會比較冗長(下面{...}省略了一百多行配置處理代碼,用來兼容Hystrix現有配置定義),看起來如下:
配置是hystrix的核心,各種策略的選擇執行都需要配置來驅動,所以,雖然在應用層面不需要太多的配置設置,但是必要的配置hystrix都會填充一個默認值,比如,hystrix默認執行超時設置的1s。Hystrix中的配置有三個層次的加載優先級,如:
最先加載Setter:Setter是用戶傳遞給Hystrix構造器的,所以優先級別最高
其次加載動態配置源:如果必要的配置在Setter里沒有找到,則在動態配置源中獲取
最后加載默認配置:如果動態配置源中也沒有找到配置,則采用默認的配置
其中動態配置源,有一個基于SystemProperties的配置實現HystrixDynamicPropertiesSystemProperties。HystrixCommand在實例化時,如果用戶沒有給到具體的配置,Hystrix每次都會去SystemProperties中尋找配置。也就是說,我們可以通過-D參數注入任意Hystrix的配置參數,都會生效。有了這個特性,可以非常簡單的結合apollo,達到hystrix配置動態生效的效果,而且所有配置兼容Hystrix原本的配置。
實現這個功能的關鍵是。系統初始化時,將hystrix.command前綴相關的配置從apollo中獲取到然后統統注入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); } }); } }
這里注意一個問題:為啥這里多設計了一個dynamic.前綴的配置,這是因為博主在測試過程中觸發了apollo配置監聽器隱藏的問題,導致Apollo的動態監聽器不生效了。Apollo配置加載是以SystemProperties為最高優先級的,當配置發生變化時,apollo會將SystemProperties覆蓋到配置之后,才比較本次配置發布是否有更新。因為我們一開始就將相關的配置加載到SystemProperties里了,所以每次變更都會被覆蓋成之前的值,導致更新判斷失效,一直進不了監聽器。如果想要動態更新,就需要維護一份apollo的配置和SystemProperties里的映射關系,而不能保持一致,這樣每次修改apollo時,就可以將維護映射關系的前綴去掉,然后將值動態更新到SystemProperties。目前的設計里,既支持原生的所有配置一次性加載,也支持dynamic.前綴拼裝原有配置動態加載
配置示例
#初始化時一次性加載 hystrix.command.default.execution.timeout.enabled = true #每次修改動態生效 dynamic.hystrix.command.default.execution.timeout.enabled = true
關于“hystrix配置中Apollo與Archaius有什么不同”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“hystrix配置中Apollo與Archaius有什么不同”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。