1、参考
多协议:http://dubbo.apache.org/en-us/docs/user/demos/multi-protocols.html
多Registry:http://dubbo.apache.org/en-us/docs/user/demos/multi-registry.html
服务分组:http://dubbo.apache.org/en-us/docs/user/demos/service-group.html
多版本:http://dubbo.apache.org/en-us/docs/user/demos/multi-versions.html
分组聚合:http://dubbo.apache.org/en-us/docs/user/demos/group-merger.html
2、多协议
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BMLsCmic-1648775999505)(http://dubbo.apache.org/docs/en-us/user/sources/images/dubbo-protocol.jpg)]
协议指Transporter这一块,包括编解码、序列化、连接等。Dubbo支持多种协议,它们性能不同,适用场景也不同。
各协议性能参考:http://dubbo.apache.org/en-us/docs/user/perf-test.html
一个Provider可以同时提供多个服务,可分别为每个服务配置单独的协议,配置如下:
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="world" />
<dubbo:registry id="registry" address="10.20.141.150:9090" username="admin" password="hello1234" />
<!-- multiple protocols -->
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:protocol name="rmi" port="1099" />
<!-- Use dubbo protocol to expose the service -->
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" protocol="dubbo" />
<!-- Use rmi protocol to expose services -->
<dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" protocol="rmi" />
</beans>
这样的话,HelloService服务使用dubbo协议,DemoService使用rmi协议。
也可以同时让一个服务支持多种协议,配置如下:
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="world" />
<dubbo:registry id="registry" address="10.20.141.150:9090" username="admin" password="hello1234" />
<!-- multiple protocols-->
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:protocol name="hessian" port="8080" />
<!-- Service exposes multiple protocols -->
<dubbo:service id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" protocol="dubbo,hessian" />
</beans>
这样helloService同时支持dubbo与hessian两种协议。
总之,Provider能够对它提供的服务分别指定不同的协议。另外同一个服务的多个实例,对于Consumer而言,它们支持的协议也可能是多种。
3、多Registry
Dubbo可以服务级别控制服务具体注册到那个Registry、注册到几个Registry。例如,同一个服务注册到多个Registry:
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="world" />
<!-- Multi registries -->
<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" default="false" />
<!-- Service register to multiple registries -->
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="hangzhouRegistry,qingdaoRegistry" />
</beans>
一个服务注册到两个Registry。
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="world" />
<!-- Multi registries -->
<dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" />
<!-- Service register to Chinese station registry -->
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="chinaRegistry" />
<!-- Service register to international station registry -->
<dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" registry="intlRegistry" />
</beans>
不同的服务注册到不同的Registry。
多注册中心的一个应用是区别不同配置的同一服务。比如:CRM 需同时调用中文站和国际站的 PC2 服务,PC2 在中文站和国际站均有部署,接口、版本号、实现类都一样,在外观上这两个服务实例没有区别,但连的数据库不样,相当于配置不一样。Consumer端可作如下配置:
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="world" />
<!-- 多注册中心配置 -->
<dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" />
<!-- 引用中文站服务 -->
<dubbo:reference id="chinaHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="chinaRegistry" />
<!-- 引用国际站站服务 -->
<dubbo:reference id="intlHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="intlRegistry" />
</beans>
这样的话Consumer端就有HelloService服务的两个版本了,一个id是chinaHelloService,另一个是intlHelloService。
4、服务分组
如果服务实现的接口、版本号相同,但是上体的实现类不同,则可以通过服务分组的方式加以区分,Provider端可以这样配置:
<dubbo:service group="vipuser" interface="com.xxx.IndexService" ref="vip class" />
<dubbo:service group="commonuser" interface="com.xxx.IndexService" ref="common class" />
同样的IndexService服务,分成vip与common两种,前者可能实现更多的附加功能。
Consumer端引用:
<dubbo:reference id="feedbackIndexService" group="feedback" interface="com.xxx.IndexService" />
<dubbo:reference id="memberIndexService" group="member" interface="com.xxx.IndewxService" />
同样的IndexService服务,分别来自两个不同的组,并分配不同的ID。
如果服务有多个组,但是Consumer并不打算区分,则可这样配置:
<dubbo:reference id="barService" interface="com.foo.BarService" group="*" />
用星号代替组名。
5、多版本服务
一般当服务对应的接口发生变化时,如增加了某些接口、删除了某些接口、接口参数发生变化,会对服务进行版本升级。多数情况下不单单是Provider的服务需要升级,往往Consumer端的Client也需要升级,因为接口发生变化了。一般都采用逐步迁移的方案。比如有5个旧版本的服务实例,有10个旧版本的Consumer,在负荷低时,先升级一个服务实例,再升级两个Consumer,观察一下,如果没有问题就循环此过程,直接全部完成升级。
配置如下:
Provider端提供服务:
<dubbo:service interface="com.foo.BarService" version="1.0.0" ref="1.0.0 class/>
升级的时候换一个版本号指定相应的实现类。
Consumer端引用:
<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />
长级的时候就换成新的版本号。
如果Consumer端不需要区分版本,则:
<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />
5、分组聚合
在服务分组中,可以把服务按实现的不同,分成多个组。Consumer端在引用服务时,group="*"表示不区分服务分组,可调用其中的任何一个。
分组聚合则不同,Providier端的服务也是分组的,但是Consumer在调用时,每个分组的服务实例都调用一回,并且最后需要把返回的结果作一次合并。这个功能有点像大数据计算中的分块计算,某种程序上把一个大的复杂的任务在Consumer端分解成多个小块,然后每一块发给不同的分组,最后合并返回的结果,这样就充分利用了系统的分布式计算能力,有可能更快的返回计算结果。
分组聚合主要是Consumer端的行为,配置如下:
<dubbo:reference interface="com.xxx.MenuService" group="*" merger="true" />
合并所有分组。
<dubbo:reference interface="com.xxx.MenuService" group="aaa,bbb" merger="true" />
合并指定分组。
<dubbo:reference interface="com.xxx.MenuService" group="*" merger="true">
<dubbo:method name="getMenuItems" merger="false" />
</dubbo:reference>
只对服务的特定方法进行分组合并,其它方法正常处理。
Dubbo根据返回结果的类型调用匹配的合并器。合并器要实现固定的接口,其中有一个merge方法,假如分组返回的类是aaa类,然后Dubbo发现系统中有一个合并器,它的merge方法的参数类型也是aaa类,那么就会调用这个merger方法,当然这个合并器开发者要自行实现。如果有两个合并器类,它们的merge方法参数类型也相同,都是aaa,这个时候在配置分组合并的时候就要明确指明使用那个合并器,配置如下:
<dubbo:reference interface="com.xxx.MenuService" group="*">
<dubbo:method name="getMenuItems" merger="mymerge" />
</dubbo:reference>
另外,也可以不指定合并器,利用返回结果类的某个成员进行分组合并,当然这个成员的参数类型必需是返回结果类型本身。配置如下:
<dubbo:reference interface="com.xxx.MenuService" group="*">
<dubbo:method name="getMenuItems" merger=".addAll" />
</dubbo:reference>
在方法名前边加上一个点进行区分。
Merge的扩展参考:http://dubbo.apache.org/zh-cn/docs/dev/impls/merger.html
基实就是实现Dubbo的合并器接口,实现其中的merge方法,然后修改一下Dubbo的配置文件,给这个合并器起一个名字并指定具体的实现类,告诉它有这个合并器就可以了。例如修改项目配置文件META-INF/dubbo/org.apache.dubbo.rpc.cluster.Merger,在其中加入:
xxx=com.xxx.XxxMerger
xxx就是合并器的名字,后边的类就是自己实现的代码。
。