dubbo多个注册中心

/ Dubbo / 没有评论 / 331浏览

dubbo支持同一个服务向多个注册中心注册,也可以将不同的服务注册到不同的注册中心中。下面我们来具体验证一下。


有时出于安全性考虑,通常会部署多个注册中心,以免因注册中心出现问题导致服务调用失败。有时如果我们只部署了某一个服务在一个注册中心中,而另一个注册中心还没有来的急部署,但另一个注册中心还依赖于此服务时,我们可以将改服务同时注册到多个注册中心中。下面为具体代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper暴露服务地址 -->
    <dubbo:registry id="zk1" address="127.0.0.1:2181" protocol="zookeeper"/>
    <dubbo:registry id="zk2" address="127.0.0.1:2182" protocol="zookeeper"/>

    <!-- 暴露服务端口 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 声明需要暴露的服务接⼝ -->
    <dubbo:service interface="com.jilinwula.api.HelloWorld" ref="helloWorldImpl" registry="zk1,zk2"/>

    <!-- component-scan自动扫描注解 -->
    <context:component-scan base-package="com.jilinwula.*"/>

</beans>

当我们将服务注册到多个注册中心时,消费端可以调用任意的注册中心,调用服务。


有时因为业务场景的原因,会将注册中心按业务分离开,也就是将不同的服务注册到不同的注册中心的,它们服务与服务之间是相互隔离的。具体代码如下:

provider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper暴露服务地址 -->
    <dubbo:registry id="zk1" address="127.0.0.1:2181" protocol="zookeeper"/>
    <dubbo:registry id="zk2" address="127.0.0.1:2182" protocol="zookeeper"/>

    <!-- 暴露服务端口 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 声明需要暴露的服务接⼝ -->
    <dubbo:service interface="com.jilinwula.api.HelloWorld" ref="helloWorldImpl" registry="zk1"/>

    <dubbo:service interface="com.jilinwula.api.DemoService" ref="demoServiceImpl" registry="zk2"/>

    <!-- component-scan自动扫描注解 -->
    <context:component-scan base-package="com.jilinwula.*"/>

</beans>

consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 调用方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper查找服务地址 -->
    <dubbo:registry id="zk1" address="127.0.0.1:2181" protocol="zookeeper"/>
    <dubbo:registry id="zk2" address="127.0.0.1:2182" protocol="zookeeper"/>

    <!-- Dubbo自动生成远程服务代理 -->
    <dubbo:reference id="helloWorld" interface="com.jilinwula.api.HelloWorld" registry="zk1"/>
    <dubbo:reference id="demoService" interface="com.jilinwula.api.DemoService" registry="zk2"/>

</beans>

当我们此时调用helloWorld和demoService服务时,则服务可以正常调用成功。如果我们将helloWorld服务的registry由zk1修改为zk2时,在调用服务时,dubbo则会抛出异常。

consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 调用方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper查找服务地址 -->
    <dubbo:registry id="zk1" address="127.0.0.1:2181" protocol="zookeeper"/>
    <dubbo:registry id="zk2" address="127.0.0.1:2182" protocol="zookeeper"/>

    <!-- Dubbo自动生成远程服务代理 -->
    <dubbo:reference id="helloWorld" interface="com.jilinwula.api.HelloWorld" registry="zk2"/>
    <dubbo:reference id="demoService" interface="com.jilinwula.api.DemoService" registry="zk2"/>

</beans>

日志:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloWorld': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Failed to check the status of the service com.jilinwula.api.HelloWorld. No provider available for the service com.jilinwula.api.HelloWorld from the url zookeeper://127.0.0.1:2182/com.alibaba.dubbo.registry.RegistryService?application=jilinwula&dubbo=2.6.0&interface=com.jilinwula.api.HelloWorld&methods=getHelloWorld&pid=13472®ister.ip=192.168.5.179&side=consumer×tamp=1531453256483 to the consumer 192.168.5.179 use dubbo version 2.6.0
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1634)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1084)
	at com.jilinwula.consumer.Consumer.main(Consumer.java:16)
Caused by: java.lang.IllegalStateException: Failed to check the status of the service com.jilinwula.api.HelloWorld. No provider available for the service com.jilinwula.api.HelloWorld from the url zookeeper://127.0.0.1:2182/com.alibaba.dubbo.registry.RegistryService?application=jilinwula&dubbo=2.6.0&interface=com.jilinwula.api.HelloWorld&methods=getHelloWorld&pid=13472®ister.ip=192.168.5.179&side=consumer×tamp=1531453256483 to the consumer 192.168.5.179 use dubbo version 2.6.0
	at com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:422)
	at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:333)
	at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:163)
	at com.alibaba.dubbo.config.spring.ReferenceBean.getObject(ReferenceBean.java:59)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
	... 6 more

如果消费者想同时连接多个注册中心时可以用|符号。具体代码如下:

consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 调用方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper查找服务地址 -->
    <dubbo:registry address="127.0.0.1:2181|127.0.0.1:2182" protocol="zookeeper"/>

    <!-- Dubbo自动生成远程服务代理 -->
    <dubbo:reference id="helloWorld" interface="com.jilinwula.api.HelloWorld"/>
    <dubbo:reference id="demoService" interface="com.jilinwula.api.DemoService"/>

</beans>

但如果我们将address参数中的|修改为逗号,则会dubbo则会抛出异常。具体修改如下:

consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 调用方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper查找服务地址 -->
    <dubbo:registry address="127.0.0.1:2181,127.0.0.1:2182" protocol="zookeeper"/>

    <!-- Dubbo自动生成远程服务代理 -->
    <dubbo:reference id="helloWorld" interface="com.jilinwula.api.HelloWorld"/>
    <dubbo:reference id="demoService" interface="com.jilinwula.api.DemoService"/>

</beans>

日志:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demoService': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Failed to check the status of the service com.jilinwula.api.DemoService. No provider available for the service com.jilinwula.api.DemoService from the url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=jilinwula&dubbo=2.6.0&interface=com.jilinwula.api.DemoService&methods=getDemoService&pid=15444®ister.ip=192.168.5.179&side=consumer×tamp=1531453714764 to the consumer 192.168.5.179 use dubbo version 2.6.0
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1634)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1084)
	at com.jilinwula.consumer.Consumer.main(Consumer.java:21)
Caused by: java.lang.IllegalStateException: Failed to check the status of the service com.jilinwula.api.DemoService. No provider available for the service com.jilinwula.api.DemoService from the url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=jilinwula&dubbo=2.6.0&interface=com.jilinwula.api.DemoService&methods=getDemoService&pid=15444®ister.ip=192.168.5.179&side=consumer×tamp=1531453714764 to the consumer 192.168.5.179 use dubbo version 2.6.0
	at com.alibaba.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:422)
	at com.alibaba.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:333)
	at com.alibaba.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:163)
	at com.alibaba.dubbo.config.spring.ReferenceBean.getObject(ReferenceBean.java:59)
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
	... 6 more

这是因为,如果我们多个注册中心之间是|连接则表示是同时连接多个注册中心,如果多个注册中心之间用逗号连接,则表示它们之间的关系是负载。又因为demoService服务只在zk2上注册了,所以,消费方调用时,则会报错,因为zk1上没有该服务(因为负载的关系,也有可能helloWorld服务报错)。