文章目录
dubbo最基础的用法就是远程调用,服务端给消费者提供服务,但是dubbo也提供了额外的一些高级用法
一、负载均衡
大型架构里面,通常不止一台机器提供服务,一个集群来提供服务。负载均衡就是把服务分摊给各个服务提供者的一种思想。
dubbo官网提供了4种负载均衡策略
1. 随机(random)
服务将会被按照权重随机打到服务提供者,这是dubbo默认的策略
2. 轮询(roundRobin)
服务器就好比一群小朋友,坐成一排,大人从左到右挨个给他们发苹果(服务)
缺点:如果其中有一个服务器处理较慢,会积累请求,卡在一台机器上,效率有所影响
3. 最少活跃调用(leastActive)
活跃数是指调用前后计数差
表现:最少活跃调用数,相同活跃数的随机
这种策略可以弥补轮询策略的缺陷,越慢的服务提供者的调用前后计数差越大,会收到更少的请求
4. 一致性Hash(ConsistentHash)
表现:相同参数的请求总是发到同一个服务提供者
如果其中一台服务器挂掉,它的业务会被平摊到其他还存在的节点
二、集群容错
1. failover
dubbo的默认容错方式
如果当前服务提供这没有执行成功,消费者会重新调用其他的服务器来执行,如果调了好几个服务器都失败,那太影响性能了,因此可以设置重试次数:
<dubbo:service retries="2" />
2. failfast
只执行一次,有错立马报错
3. failSafe
失败了就失败了,无所谓,不报错
4. failBack
失败自动恢复,后台记录失败请求,会定时重发
5. forking
一个请求同时发给多个服务器,让他们分别执行,有一个成功就行
这个方式有点耗服务器资源,但是性能和用户体验会好一点
6. broadcast
广播,要求所有的提供者都不报错
三、服务降级
如果原本的服务执行不成功,那么会干啥
举个例子:
配置一下 mock=fail:return 1;
即意味着,如果服务执行失败,结果返回1
还有一种 mock=fource:return 1;
,意味着,不进行远程调用
也可以return 方法名(去执行一定的逻辑)和抛异常
如果要执行一定的逻辑,使用方法如下:
第一步肯定是配置文件,开启mock
然后在接口那个地方创建一个xxxServiceMock,实现xxxService
四、本地存根
(图片来自dubbo官网)
从图片可以看出来,stub就是在服务执行之前先执行一下
使用方法:
<dubbo:service interface="com.vdian.demoService" stub="true" />
然后在接口那个地方创建一个类,取名为xxxServiceStub,实现一下xxxService
五、参数回调
参数回调就是服务提供者反过来调用消费者的逻辑
实现原理就是基于长连接生成反向代理
使用方式:
- 服务器端创建Listener接口(用于参数传递)
- 写好Service实现类,实现类中有方法将Listener接口作为参数
- 配置provider.xml需要这样声明:
<dubbo:service interface="com.callback.CallbackService" ref="callbackService" connections="1" callbacks="1000">
<dubbo:method name="addListener">
<dubbo:argument index="1" callback="true" />
<!--也可以通过指定类型的方式-->
<!--<dubbo:argument type="com.demo.CallbackListener" callback="true" />-->
</dubbo:method>
</dubbo:service>
- 消费者调用方法就行,不过在方法的参数中需要实现Listener接口,用来执行具体逻辑
六、泛化调用
泛化调用就是消费者调用没有事先定义好的接口。接口只在提供者里面定义了,消费者没有API也要调用相应的方法,那么就需要用到泛化调用
使用方式:
- 在服务端定义一个接口,并且创建类实现它
- spring注解,在接口的后面加上
generic="true"
- 从容器中取出接口,并且转换为GenericService,然后使用invoke方法进行调用,第一个参数是方法名,第二个参数是入参类型,第三个是传入参数的具体值
GenericService barService = (GenericService) applicationContext.getBean("barService");
Object result = barService.$invoke("sayHello", new String[] { "java.lang.String" }, new Object[] { "World" });