17.负载均衡如何实现

分析负载均衡的test case

起两个provider,前面文章中有现成的provider,起来就好。

用HelloClientTest testSayHello调用几次,观察落在哪个provider上。

分析负载均衡

对于客户端调用过程中的逻辑,比如上篇的路由,这一篇的负载均衡等等机制,都可以通过观察调用前的调用栈来分析发现。

在 com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker.doInvoke(Invocation)里面打个断点后观察他的调用栈或者用arthas观察他的调用栈,不难发现负载均衡是在 FailoverClusterInvoker.doInvoke(Invocation, List<Invoker>, LoadBalance) line: 77 中发起的:

com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(Invocation, List<Invoker>, LoadBalance)

73            Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);
74            invoked.add(invoker);
75            RpcContext.getContext().setInvokers((List)invoked);
76            try {
77                Result result = invoker.invoke(invocation);

73行是负载均衡发起的地方,也是与client发起调用时交织的地方。

看73行的com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.select(LoadBalance, Invocation, List<Invoker>, List<Invoker>)方法签名,能发现将一个invoker list送进去选一个invoker出来。

我们跟一下代码,不难发现,下面贴一下到具体的负载均衡的策略的调用栈:

RandomLoadBalance.doSelect(List<Invoker<T>>, URL, Invocation) line: 38	
RandomLoadBalance(AbstractLoadBalance).select(List<Invoker<T>>, URL, Invocation) line: 38	
FailoverClusterInvoker<T>(AbstractClusterInvoker<T>).doselect(LoadBalance, Invocation, List<Invoker<T>>, List<Invoker<T>>) line: 132	
FailoverClusterInvoker<T>(AbstractClusterInvoker<T>).select(LoadBalance, Invocation, List<Invoker<T>>, List<Invoker<T>>) line: 115	
FailoverClusterInvoker<T>.doInvoke(Invocation, List<Invoker<T>>, LoadBalance) line: 73	
FailoverClusterInvoker<T>(AbstractClusterInvoker<T>).invoke(Invocation) line: 227	
MockClusterInvoker<T>.invoke(Invocation) line: 72	
InvokerInvocationHandler.invoke(Object, Method, Object[]) line: 52	
proxy0.sayHello(String) line: not available	
HelloClientTest.testSayHello() line: 37

具体的负载均衡算法不分析了,看下对应代码还是比较清晰的。