背景
Dubbo目前支持了以下4种的负载均衡策略:
1.一致性Hash均衡算法 (ConsistentHashLoadBalance)
2.随机调用法 (RandomLoadBalance)
3.轮询法 (RoundRobInLoadBalance)
4.最少活动调用法 (LeastActiveLoadBalance)
因为业务本身是基于长链接架构,用户创建的长链接只在指定的某一台机器上,如果Dubbo调用后的目标对象不在当前服务器上,此时该服务器向RocketMQ发送一条消息,集群服务通过广播模式进行消费处理。
方案弊端:
- 依赖于消息队列的组件,额外造成网络开销
- 每次请求都是盲盒行为,最少一次,最多2次请求,也会占用其他机器的性能开销,虽然开销不大。
- 链路被无形中拉长了,针对于分布式服务而言,链路越短,出错的概率越小。
RocketMQ集群消费模式
自定义实现策略
Dubbo本身的 LoadBalance 就是一个被 SPI 定义的接口类,官方本身是支持LoadBalance的重写的(一般针对远程调用服务而言,例如Spring Cloud也是支持自定义Ribbon的)。实现的方式也较为简单
1.继承 AbstractLoadBalance.class 实现select方法
public class TestLoadBalance extends AbstractLoadBalance {
private static final Logger log = LoggerFactory.getLogger(TestLoadBalance.class);
public static final String NAME = "testLoadBalance";
@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
log.info("load for test balance");
return invokers.get(0);
}
}
2.在/resources/MET-INF 下注入自己实现的 LoadBalance,使得 Dubbo能够通过 ExtensionLoader 加载到对应的实现
testLoadBalance=com.star.game.main.server.provider.TestLoadBalance
3.在Dubbo的 loadBalance 配置里增加自己定义的 Name 即可。
代码运行截图:
至此就完成了初步的LoadBalance重写,但是很明显,该方案并不能解决我们说的问题,我们诉求的点是:
1.根据请求的字段获取到对应的服务器
2.该服务器地址并不是一个策略,可能需要通过三方获取,也有可能需要通过其他事件监听获取并且缓存记录下来。
实现思路
1.通过添加注解的方式,将需要定向调度的RPC管理起来ÿ