RestTemplate简介:
RestTemplate 是spring resources 中一个访问第三方restful api接口的网络请求框架。resttemplate 的设计原则和其他spring template [jdbc template,jms template]类似,都是为执行复杂任务提供了一个具有默认行为的简单方法。
RestTemplate是用来消费REST 服务的,所以RestTemplate的主要方法都与REST的http 协议的一些方法紧密相连,例如head,get,post,put,delete , options等方法,这些方法在RestTimplate类对应的方法为headForHeaders(),getForObject(),postForObject(),put(),delete()方法等。
实例:获取https://www.baidu.com 的网页html 代码:
@ApiOperation("获取百度html 网页代码")
@GetMapping("baidu")
public String getBaidu(){
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject("https://www.baidu.com/",String.class);
}
RestTemplate支持常见的http 协议的请求方法,例如post ,put ,delete 等,所以用RestTimplate 很容易构建restful api 。RestTemplate支持xml ,json 数据格式,默认实现了序列化,可以自动将json 字符串转换为实体。实例:
UserInfo user = restTimplate.getForObject("https://xxx.xxx.com/",User.class);
Ribbon 简介:
负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式:
一种是独立进程单元,通过附加均衡策略,将请求转发到不同的执行单元上,例如ngnix 。
另一种是将负载均衡逻辑以代码的形式封装到服务消费者的客户端上,服务消费者客户端维护了一份提供者的信息列表,有了信息列表,通过负载均衡策略将请求分摊给多个服务提供者,从而达到了负载均衡的目的。
Ribbon 是netflix 公司开源的一个负载均衡的组件,它属于第二种方式,是将负载均衡逻辑封装到客户端中,并且运行在客户端的进程里。ribbon 是一个经过了云端测试的IPC库,可以很好的控制http 和tcp 客户端的负载均衡行为。
在spring cloud 构建的微服务系统种,ribbon作为服务消费者的负载均衡器,有两种使用方式:
1.和RestTemplate 相结合
2.和feign 相结合。feign 已经默认集成了ribbon。
ribbon-loadbalancer: | 可以独立使用或与其他模块一起使用的负载均衡器API |
ribbon-eureka: | ribbon 结合eureka 客户端的API,为负载均衡提供动态服务注册列表信息 |
ribbon-core | ribbon 的核心API |
依次启动:
java -jar eureka.server.jar --spring.profiles.active=peer1
java -jar eureka.server.jar --spring.profiles.active=peer2
启动eureka client ----启动 eureka-ribbon-client
访问:http://localhost:8764/hi?name=jie
LoadBalancerClient 简介:
负载均衡的核心类为LoanBalancerClient ,LoanBalancerClient可以获取负载均衡的服务提供者的实例信息。LoanBalancerClient是从eureka client 获取服务注册列表信息的,并将服务注册列表信息缓存了一份。再LoanBalancerClient 调用choose()方法的时候,根据负载均衡选择一个服务实例的信息,从而进行了负载均衡。LoanBalancerClient 也可以不从eureka client 获取注册列表信息,但是需要自己维护一份服务注册列表信息。
choose()方法用于选择具体服务实例。该方法通过getServer()方法去获取实例,最终交给ILoadBalancer类去选择服务实例。
ILoadBalancer 在ribbon-loadbalancer的jar 包下,ILoadBalancer 是一个接口,该接口定义了一系列实例负载均衡的方法:
public interface ILoadBalancer {
void addServers(List<Server> var1);
Server chooseServer(Object var1);
void markServerDown(Server var1);
/** @deprecated */
@Deprecated
List<Server> getServerList(boolean var1);
List<Server> getReachableServers();
cList<Server> getAllServers();
}
addServer() | 添加一个server 方法 |
chooseServer() | 根据key去获取server |
markServerDown | 标记某个服务下线 |
getReachableServers | 获取可用的server集合 |
getAllServers | 获取所有的server集合 |
DynamicServerListLoadBalancer 需要配置 IClientConfig,IRule,IPing,ServerList,ServerListFilter和 ILoadBalancer。
IClientConfig 用于配置负载均衡的客户端,IClientConfig的默认实现类为DefaultClientConfigImpl.
IRule用于配置负载均衡的策略,有三个方法,其中choose()是根据key来获取server实例,setLoadBalancer()方法和getLoadBalancer()是用来设置和获取ILoadBalancer的。
IRule 有很多默认的实现类,这些实现类根据不同的算法和逻辑来处理负载均衡的策略。IRule的默认实现类有以下7种:
BestAvailableRule | 选择最小请求数 |
ClientConfigEnabledRoundRobinRule | 轮询 |
RandomRule | 随机选择一个server |
RoundRobinRule | 轮询选择server |
RetryRule | 根据轮询的方式重试 |
weightedResponseTimeRule | 根据响应时间去分配一个weight,weight越低,被选择的可能性就越低 |
ZoneAvoidanceRule | 根据server的zone区域和可用性来轮询选择 |
IPing 的实现类有PingUrl,PingConstant,NoOpPing, DummyPing 和NIWSDiscoveryPing。
PingUrl | 真实的去ping 某个url ,判断其是否可用 |
PingConstant | 固定返回某服务是否可用,默认返回true,即可用 |
NoOpPing | 不去ping,直接返回true,即可用 |
DummyPing | 直接返回true,并实现了initWithNiwsConfig方法 |
NIWSDiscoveryPing | 根据DiscoveryEnabledServer 的InstanceInfo 的InstanceStatus去判断,如果InstanceStatus.UP ,则可用,否则不可用。 |
盖棺定论:
ribbon 的负载均衡主要是通过LoadBalancerClient 来实现的,而LoadBalancerClient 具体交给了ILoadBalancer来处理,ILoadBalancer 同故宫配置IRule,IPing 等,而eureka client 获取注册列表的信息,默认每10秒向 eureka client 发送一次ping,进而检查是否需要更新服务的注册列表信息,最后,在得到服务注册列表信息后,ILoadBalancer 根据IRule的策略进行负载均衡。
而RestTemplate 加上@LoadBalancer 注解后,在远程调度时能够负载均衡,主要是维护了一个被@LoadBalance注解的RestTemplate列表,并给该列表种的RestTemplate对象添加了拦截器,在拦截器的方法中,将远程调度方法交给了ribbon的负载均衡器LoadBalancerClient 去处理,从而实现了负载均衡的目的。