Dubbo 缺省會在啟動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止 Spring 初始化完成,以便上線時,能及早發現問題,默認 check="true"
。
可以通過 check="false"
關閉檢查,比如,測試時,有些服務不關心,或者出現了循環依賴,必須有一方先啟動。
另外,如果你的 Spring 容器是懶加載的,或者通過 API 編程延遲引用服務,請關閉 check,否則服務臨時不可用時,會拋出異常,拿到 null 引用,如果 check="false"
,總是會返回引用,當服務恢復時,能自動連上。
示例
1.通過 spring 配置文件
關閉某個服務的啟動時檢查 (沒有提供者時報錯):
<dubbo:reference interface="com.foo.BarService" check="false" />
關閉所有服務的啟動時檢查 (沒有提供者時報錯):
<dubbo:consumer check="false" />
關閉注冊中心啟動時檢查 (注冊訂閱失敗時報錯):
<dubbo:registry check="false" />
2.通過 dubbo.properties
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
3. 通過 -D 參數
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
配置的含義
dubbo.reference.check=false,強制改變所有 reference 的 check 值,就算配置中有聲明,也會被覆蓋。
dubbo.consumer.check=false,是設置 check 的缺省值,如果配置中有顯式的聲明,如:<dubbo:reference check="true"/>,不會受影響。
dubbo.registry.check=false,前面兩個都是指訂閱成功,但提供者列表是否為空是否報錯,如果注冊訂閱失敗時,也允許啟動,需使用此選項,將在后台定時重試。
上面是摘自官網的解釋,下面研究其在springboot中關閉檢查服務。
1.比如我們啟動一個正常的web程序,其service層采用dubbo服務方式獲取,我們不提供服務的提供者啟動項目
報錯創建bean錯誤:
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 2019-03-25 17:36:41.523 ERROR 4560 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mobileLoginController' defined in file [E:\xiangmu2\springboot-ssm-soa\springboot-ssm-web\target\classes\cn\qlq\controller\mobile\MobileLoginController.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: mobileLoginController; nested exception is java.lang.IllegalStateException: Failed to check the status of the service cn.qlq.service.user.TokenService. No provider available for the service cn.qlq.service.user.TokenService:1.0.0 from the url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=consumer&dubbo=2.6.0&interface=cn.qlq.service.user.TokenService&methods=updateIfExistsTokenByTokenStr,findTokenByUsername,deleteInvalidToken,addOrUpdateToken&pid=4560®ister.ip=10.10.24.4&revision=0.0.1-SNAPSHOT&side=consumer×tamp=1553506600929&version=1.0.0 to the consumer 10.10.24.4 use dubbo version 2.6.0 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
也就是bean默認是檢查的,所以springboot項目啟動的時候檢查依賴關系的時候從dubbo服務中獲取不到對應的服務,所以報錯。
2.修改bean注入的檢查為false,只需要在注解的check屬性改為false即可(也就是不檢查服務),默認是true
修改之后服務可以正常啟動,我們查看zookeeper注冊中心的服務信息,發現沒有提供者,如下:
當我們訪問的時候報錯信息如下:(沒有服務提供者)
com.alibaba.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:2181 for service cn.qlq.service.user.UserService:1.0.0 on consumer 10.10.24.4 use dubbo version 2.6.0, may be providers disabled or not registered ?
at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:572) ~[dubbo-2.6.0.jar:2.6.0]
at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:73) ~[dubbo-2.6.0.jar:2.6.0]
at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:265) ~[dubbo-2.6.0.jar:2.6.0]
at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:224) ~[dubbo-2.6.0.jar:2.6.0]
at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:70) ~[dubbo-2.6.0.jar:2.6.0]
at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:51) ~[dubbo-2.6.0.jar:2.6.0]
at com.alibaba.dubbo.common.bytecode.proxy1.getPageInfoUsers(proxy1.java) ~[dubbo-2.6.0.jar:2.6.0]
啟動服務的提供者,從zookeeper注冊中心查看已經有提供者,訪問也不會報錯:
通過這個我們也明白了dubbo服務在zookeeper注冊中心注冊的服務的生產者和消費者信息都存在zookeeper的節點上。