本节主要学习ribbon,虽然feign更常用,但是其本身的实现也依赖于ribbon。
无论是什么负载均衡设备,都会维护一个下挂可用的服务端清单,通过心跳检测剔除故障节点。当客户端发送请求到负载均衡设备时,按照某种算法选取一台服务端地址,发送请求。
【客户端负载均衡和服务端负载均衡】
先说说服务端负载均衡:如常见的nginx,它通过接收请求,将请求分发到通过算法计算出的地址实现服务端负载均衡,请注意,这里nginx维护的可用服务清单是在服务端的。
再说说客户端负载均衡:ribbon就是典型的一例,客户端负载均衡要求服务清单是在客户端的,ribbon通过和注册中心联手合作,轮询访问达到负载均衡。
我们使用ribbon很简单,只需要调用被@LoadBalanced注解修饰过的RestTemplate实现面向服务的接口调用即可。
在RestTemplate中,对请求通过如下几种方式调用:
【GET请求】getForEntity / getForObject
【POST请求】 postForEntity / postForObject
以上都是通过传入uri、class、param来实现获取返回,如果对相应body外的东西更感兴趣,可以用Entity版本方法,如果只是对正文有兴趣,Object版本返回的方法包装的更好。
此外post请求还有postForLocation方法,通过发送资源到服务端,返回一个URI.
【关于POST请求和PUT请求】POST请求增资源,PUT请求改资源(不会重复执行,后一次会覆盖前一次,类似map)
put和delete请求之久通过put/delete即可调用
分析源码:
/**
* Annotation to mark a RestTemplate bean to be configured to use a LoadBalancerClient
* @author Spencer Gibb
*/
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}
通过对@LoadBalanced注解的源码上的说明,我们知道,这个注解用来对RestTemplate采用LoadBalancerClient的配置,顺藤摸瓜,看一下LoadBalancerClient类,发现其中只有简单的三个方法,提供使得可以从负载均衡器中挑选服务实例执行请求内容的execute方法和构建合适的host:port形式的URI的constructURI方法。这些信息还远远不够,深一步看LoadBalancerClient的所在包,更深一步观察类LoadBalancerAutoConfiguration:
@Configuration
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {
首先是类头,根据类头可以看到,ribbon实现负载均衡自动化配置需要:
RestTemplate类存在于环境中
LoadBalancerClient实现Bean存在于上下文中
【关于@Configuration注解和@EnableConfigurationPorpertis注解】在标注了@Configuration注解的类,你可以把它看做一个xml文件,里面可以通过使用@Bean注解来类似xml文件对bean对象的注册。而@EnableConfigurationProperties则可以让你控制注入Bean的时机。
该类主要是创建了一个LoadBalancerInterceptor的实例,用来对客户端请求拦截,达到负载均衡。
还创建了一个RestTemplateCustomizer的实例,用来给RestTemplate对象增加拦截器。
以及维护了一个被@LoadBalanced注解修饰的RestTemplate对象列表,并给予初始化。
通过追溯我们可以对ribbon实现的一套负载均衡策略有如下:
对标记有@LoadBalanced注解的RestTemplate对象加上拦截器,拦截请求做负载均衡。
↓
请求拦截,获取服务实例,根据策略选择具体服务实例,重构URI,执行请求。
feign调用(主要特色是整合了ribbon和hystrix,并且提供了一种声明式的客户端形式)
通过@EnableFeignClient启动feign组件
通过@FeignClient来绑定具体该服务的名称
只需要创建一个interface来模拟本地调用调用服务即可。
最后通过在controller类中调用interface中的方法实现服务的调用。
配合hystrix配置可以达到服务降级