對dubbo啓動時檢查check屬性的一些個人理解

對於dubbo框架,對服務引用啓動時檢查的check配置,官方文檔的描述是這樣的:

Dubbo 缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止 Spring 初始化完成,以便上線時,能及早發現問題,默認 check="true"

可以通過 check="false" 關閉檢查,比如,測試時,有些服務不關心,或者出現了循環依賴,必須有一方先啓動。

另外,如果你的 Spring 容器是懶加載的,或者通過 API 編程延遲引用服務,請關閉 check,否則服務臨時不可用時,會拋出異常,拿到 null 引用,如果 check="false",總是會返回引用,當服務恢復時,能自動連上。

嗯,總結一下,可以解決循環依賴問題,如果配置爲true,則開始加載spring容器時會拋異常出來,如果容器懶加載,則需要關閉check以保證應用啓動時對可能被懶加載引用的dubbo服務bean不要被檢查。

這些訊息很容易把部分開發者的理解引向:dubbo的check如果爲true則永遠在容器初始化時檢查,而懶加載所加載的bean注入的多是容器啓動時還未初始化完成的dubbo服務,所以爲了讓懶加載的bean在加載時能夠注入已經初始化完成的服務,check需設置成false來避開容器初始化時的檢查,以防bean還未加載,在應用啓動時就先報錯了。而如果非懶加載的bean注入了確定在當前應用啓動後纔會初始化的服務,即便引用此服務時配置了check=false,也僅僅是在應用啓動時不會拋出異常,在使用時依然無法連上服務,因爲並沒有使用懶加載爲其延遲出初始化的時間。

這也會產生一個理解誤區:想要引用在當前應用之後初始化的服務,則需要使用懶加載策略延遲出服務初始化的時間,而check=false這個配置屬性則只是爲了配合懶加載避過容器初始化時的檢查報錯而已。


我們假定一個應用場景,A應用與B應用的beanA與beanB同時注入了serviceC,但serviceC需要等A應用與B應用都啓動後纔可以去初始化,beanA爲lazy-init模式,beanB則是立即加載,那這個時候beanA與beanB該怎麼初始化呢?

這個時候一定會引發思考:嘿,這還不簡單,設置check爲false解決循環依賴,beanA是懶加載的,check爲true的話應用A啓動容器加載時就會檢查,但這個時候serviceC一定是沒有初始化好的,如果報錯的話,那到了beanA加載的時候,serviceC就注不進去了吧,我把它設置成false,這樣等beanA初始化的時候就可以讓已經初始化好了的serviceC正常加載了。beanB是立即加載的,如果配置check=false,雖然應用啓動不會報錯了,但容器上來就注入沒初始化好的serviceC豈不是還注不進去?那這個check=false對於beanB來說有什麼用呢,check=false只是爲了和懶加載一起解決循環依賴存在的東西麼?beanB又該如何正常加載服務呢?

起碼比較笨的我當時是這樣想的。於是我進行了測試:

實際在我測試時,對於懶加載的bean所注入的服務引用,無論check配置值爲true或爲false,都不會影響spring容器的加載。check配置爲false對於懶加載及立即加載的bean並沒有差異,都可以在服務初始化完成後繼續連上。差異產生於check爲true時。

那麼檢查是在哪裏進行的?這步操作實際是根據bean的初始化時機進行的,對於非懶加載的bean,bean初始化的時候等同於容器初始化的時候,如有未初始化完成的服務,check=true則會阻止容器的啓動,讓應用在啓動時就報錯,讓開發者在應用啓動時就知道:我有未初始化好的服務引用正在注入,使用時會出現問題,從而及時加以調整。

對於懶加載的bean而言,bean初始化的時候並非是容器初始化的時候,這種條件下check=true會導致在使用這個bean時才執行檢查,如果這個時候bean所注入的服務引用還未初始化完成,則檢查機制會拋出異常,並注入null引用,這時容器已經加載完成,應用也已啓動,除非應用重啓,否則使用時不會再次連上服務,null引用會導致nullpoint異常的產生,爲了避免這種情況,對於懶加載的bean,應將check設置爲false,並非是要避免應用啓動時的異常,而是要避免bean的異常初始化導致的錯誤bean產生。這是配置check=false對於懶加載bean所注入服務引用的必要性真正所在。


再次總結,根據官方文檔的描述,理解不到位的開發者難免會將循環依賴問題與懶加載和check=false的配置連起來思考,這樣難免會陷入死結,最後理解爲配置check=false來幫助懶加載解決循環依賴的問題。

首先check的配置在立即加載的環境下可以來檢查是否有服務未初始化,設置爲true,如容器初始化時有未初始化的服務被注入可拋出異常讓應用初始化無法完成,設置爲false則可以不影響應用的啓動,後續服務初始化完成後依然可以正常連上。也就是說check=false的配置本身可以解決循環依賴的問題。

懶加載是一種bean加載策略,並非和dubbo有直接的聯繫,也並非直接爲了解決服務的循環依賴而存在,這種加載方式主要作用在於節約資源,提升性能,亦可以解決循環依賴的問題,只是如有加載了dubbo服務引用的bean要應用懶加載策略,需要check設爲false來防止出現未完全裝配的bean影響應用的正常運行。

以上隨筆記錄爲個人理解,如有任何問題望大家在評論中多加指正


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章