摘要:最近一個使用的項目中需要進行性能調(diào)優(yōu)。是不允許進入進行操作的。如上的寫法表示和是啟用的。從開始提供的注解。最后啟用這兩個在項目啟動入口小結(jié)通過上述幾步,在項目啟動時通過注解的條件判斷,實現(xiàn)不同的裝配,從而啟用不同的。
最近一個使用Spring的項目中需要進行性能調(diào)優(yōu)。方式基本上是編寫新的代碼實現(xiàn)原來一樣的業(yè)務(wù)邏輯,只是實現(xiàn)方式有一些調(diào)整,例如增加cache,優(yōu)化算法等等。
一開始大家希望直接在原有代碼基礎(chǔ)上修改,但是這樣一來,就要跟上每周一次的發(fā)布節(jié)奏,一周搞定難度太大。于是決定拷貝出的package來重構(gòu)。在沒啟用之前這個package下都是dead code。這樣做的好處有幾點:
在調(diào)優(yōu)后的code啟用前,業(yè)務(wù)至少不會受影響。
利用docker的特性,可以實現(xiàn)灰度發(fā)布,比如啟動兩個docker,一個是老的code,一個啟用新的code,利用nginx實現(xiàn)分流。
灰度發(fā)布后發(fā)現(xiàn)有緊急bug,只需要devOps修改一點配置,重啟docker可以再切回老的code。
出發(fā)點既然要實現(xiàn)上述第三點,也就是利用配置來實現(xiàn)切換,那么這個Enable的flag就不應(yīng)該寫到代碼里,甚至是配置文件里,因為項目啟動都是在docker中通過spring-boot的cmd直接啟動的。DevOps是不允許進入docker進行操作的。
實現(xiàn)想到我們的整個部署架構(gòu)是基于Kubernetes的,可以通過修改工程的deployment.yaml文件來實現(xiàn)。原理就是deployment里面設(shè)置一個docker的Env,Key是FeatureToggle,Value可以是這樣FeatureA,FeatureB ,當docker啟動時,JVM(Java代碼)可以通過System.getenv()來獲得環(huán)境變量,從來知道這個Feature是需要啟用還是不啟用。如上的寫法表示FeatureA和FeatureB是啟用的。
我們可以寫一個簡單的接口實現(xiàn)來判斷:
public boolean isFeatureEnable(String featureName) { // 用System.getenv("FeatureToggle")讀取環(huán)境變量判斷是否包含參數(shù)的featureName // ... }進一步使用
雖然我們有了判斷方法,但是因為項目組的人都有潔癖,我們不希望代碼中到處都是
if(isFeatureEnable(featureA)) { // new code } else { // old code }
這樣實在是太ugly了。
我們需要利用spring的IoC特性來切換implementations。Spring從4.0開始提供Conditional的注解。結(jié)合@Configuration就可以實現(xiàn)app啟動時的不同Bean的注入。
寫一個FeatureA的Condition Class
public class FeatureACondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return isFeatureEnable("featureA") } }
再寫一個Spring的Configuration來使用這個Condition
@Configuration @Conditional(FeatureACondition.class) public class FeatureAConfiguration { @Bean(name="bizService") public BizService bizService(){ return new EnhancedBizService(); } }
當然如果要實現(xiàn)互斥的切換,即啟用FeatureA另一個Bean就不能加載的話,那么再寫一個NotFeatureA的Configuration就可以了。
@Configuration @Conditional(NotFeatureACondition.class) public class NotFeatureAConfiguration { @Bean(name="bizService") public BizService bizService(){ return new OldBizService(); } }
這樣一來,當FeatureA啟用時BizService這個interface的實現(xiàn)就是EnhancedBizService,反之它的實現(xiàn)就是OldBizService。
當然你在configuration上用@ComponentScan,@Import等等都是沒問題的,在啟動時都會最先判斷Conditional,如果不滿足spring根本不會繼續(xù)下面的掃描或者加載操作。
最后啟用這兩個Config
在項目啟動入口
@SpringBootApplication @Import({NotFeatureAConfiguration.class, FeatureAConfiguration.class}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }小結(jié)
通過上述幾步,在spring項目啟動時通過conditional注解的條件判斷,實現(xiàn)不同Bean的裝配,從而啟用不同的Feature。
對于Devops而言,只需要在deployment里面修改Env的內(nèi)容,再重啟deploy這個app就可以實現(xiàn)Feature Toggle了。即使你不使用Kubernetes,docker-compose也是一樣的道理。
通過修改docker-compose.yml實現(xiàn):
environment: - FeatureToggle=FeatureA,FeatureB - SESSION_SECRET
總而言之就是充分利用OO語言的優(yōu)勢,實現(xiàn)可拔插的FeatureToggle。接下來我們還會繼續(xù)研究如何Runtime的啟用Feature,我也發(fā)現(xiàn)了一個已有的輪子togglz。如果有朋友用過,歡迎反饋使用感受。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/65246.html
摘要:顧名思義,其主要作用是解析標簽。本例中沒有用到上述的注解,所以均為。繼續(xù)追蹤這行代碼的內(nèi)部實現(xiàn)獲取的名稱調(diào)用的方法注冊過程見處理的別名,本例中沒有別名,不進入循環(huán)的具體內(nèi)容有待研究,不展開。到此為止,已經(jīng)被注冊到中。 接上篇 3 reader 注冊配置類 該 part 的起點: public AnnotationConfigApplicationContext(Class... ann...
摘要:用法先創(chuàng)建個組件,,,分別在類上加上注解。發(fā)現(xiàn)有一個屬性源碼注釋這樣說的自動檢測使用組件。在的方法中,表示不匹配,代表匹配。這就說明使用注冊組件有種方式。 Spring注解應(yīng)用篇--IOC容器Bean組件注冊 這是Spring注解專題系類文章,本系類文章適合Spring入門者或者原理入門者,小編會在本系類文章下進行企業(yè)級應(yīng)用實戰(zhàn)講解以及spring源碼跟進。 環(huán)境準備 編譯器IDEA...
摘要:這里有一個參數(shù),主要是用來指定該配置項在配置文件中的前綴。創(chuàng)建一個配置類,里面沒有顯式聲明任何的,然后將剛才創(chuàng)建的導(dǎo)入。創(chuàng)建實現(xiàn)類,返回的全類名。創(chuàng)建實現(xiàn)類,實現(xiàn)方法直接手動注冊一個名叫的到容器中。前言 小伙伴們是否想起曾經(jīng)被 SSM 整合支配的恐懼?相信很多小伙伴都是有過這樣的經(jīng)歷的,一大堆配置問題,各種排除掃描,導(dǎo)入一個新的依賴又得添加新的配置。自從有了 SpringBoot 之后,咋...
摘要:通過操作系統(tǒng)進行條件判斷,從而進行配置。分別對布爾,字符串和數(shù)字三種類型進行判斷。通過指定的資源文件是否存在進行條件判斷,比如判斷來決定是否自動裝配組件。判斷當前環(huán)境是否是應(yīng)用。 Spring Boot中的那些Conditional spring boot中為我們提供了豐富的Conditional來讓我們得以非常方便的在項目中向容器中添加Bean。本文主要是對各個注解進行解釋并輔以代碼...
閱讀 3469·2021-09-02 09:53
閱讀 1793·2021-08-26 14:13
閱讀 2750·2019-08-30 15:44
閱讀 1313·2019-08-30 14:03
閱讀 1962·2019-08-26 13:42
閱讀 3014·2019-08-26 12:21
閱讀 1302·2019-08-26 11:54
閱讀 1899·2019-08-26 10:46