微服務通訊之feign整合負載均衡
阿新 • • 發佈:2020-10-12
## 前言
書接上文,feign介面是如何註冊到容器想必已然清楚,現在我們著重關心一個問題,feign呼叫服務的時候是如何抉擇的?上一篇主要是從讀原始碼的角度入手,後續將會逐步從軟體構架方面進行剖析。
### 一、ReflectiveFeign.FeignInvocationHandler
從上文知道feign介面呼叫實質上是呼叫的對應的動態代理介面的InvocationHandler,跟蹤原始碼發現預設的InvocationHandler實現就是FeignInvocationHandler。現在我們看一下這個FeignInvocationHandler.invoke(...)方法。
```
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("equals".equals(method.getName())) {
try {
Object otherHandler =
args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
return equals(otherHandler);
} catch (IllegalArgumentException e) {
return false;
}
} else if ("hashCode".equals(method.getName())) {
return hashCode();
} else if ("toString".equals(method.getName())) {
return toString();
}
// dispath 是快取的method 以及 method對應的MethodHandler
return dispatch.get(method).invoke(args);
}
```
從程式碼中可以看到他是直接從快取中拿到對應的MethodHandler,然後呼叫的MethodHandler的invoke方法。我們看一下MethodHandler都有哪些實現:
![](https://img2020.cnblogs.com/blog/871695/202010/871695-20201009103534233-955245249.png)
可以看到就兩個實現, DefaultMethodHandler處理的是feign介面中的Default修飾的方法。我們呼叫的遠端介面用的是SynchronousMethodHandler實現。那麼可以看到我們最終對feing介面的某個方法的呼叫實際上呼叫的是SynchronousMethodHandler.invoke(...)方法。跟蹤程式碼發現,最終呼叫的是SynchronousMethodHandler持有的Client的例項的execute方法。那麼我們看一下Client都有那些實現:
![](https://img2020.cnblogs.com/blog/871695/202010/871695-20201012154336226-214713265.png)
這裡跟蹤SynchronousMethodHandler的建立過程發現Client的建立是按照如下邏輯進行的(FeignClientFactoryBean.loadBalance):
```
pr