springcloudfeign实现原理,如何实现负载均衡?
首先说明一下,feign只是一个声明式的Http客户端,提供以声明式的方式定义Http调用。本身并没有实现负载均衡,负载均衡是ribbon实现的,feign只是使用而已。
我从不使用feign进行接口调用开始,到使用feign进行接口调用,来说明使用和不使用feign的区别以及如何实现负载均衡的。不使用Feign的调用
不使用Feign的情况下,进行接口调用,一般都是使用Spring提供的RestTemplate。RestTempate提供了很多调用接口的方法,你可以简单的把RestTemplate理解为是Spring提供的HttpClient。
如果要实现负载均衡,那么只需要加一个LoadBalanced注解,就像下面这样:
那它是怎么实现负载均衡的呢?简单梳理一下源码:
LoadBalancerAutoConfiguration中有下面这段代码,它会将所有有LoadBalanced注解的RestTemplate注入进来
然后通过下面的逻辑,将负载均衡逻辑给添加进去
RestTemplate会在执行之前,先执行拦截器,然后去执行最终的请求
而拦截器中有负载均衡逻辑
首先客户端从服务列表中获取到所有的服务列表信息客户端按照负载均衡算法逻辑,选择一个服务进行调用具体代码流程比较复杂,这里不具体说明,后续可能会专门写几篇关于SpringCloud源码分析的文章问题
使用RestTemplate有什么问题呢?
和RestTemplate强依赖,不利于扩展或重构
和本地接口调用方式不统一
我们来看看使用Feign后会变成什么情况。使用Feign
假设我要调用一个远程接口,获取用户的信息。那么我们可以这么写:
1处,注解UserApiService为FeignClient,其中的name是需要调用的应用的AppName,即注册到注册中心上的名字2处,声明调用的接口的地址和Method,这里是apigetuserinfo,GET请求。1、2结合,即该接口访问的地址是GEThttp:USERapigetuserinfo3处,请求的参数。完整的请求是GEThttp:USERapigetuserinfo?userNameivanamp;password123456
怎么调用呢?
调用方式是不是和普通的接口一样?调用端根本就不必关系UserApiService是一个本地实现,还是一个远程调用。这就解决了上面提到的两个问题。