1.整合RestTemplate实现远程调用服务
1.1 引入Maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
三个依赖,一个Eureka客户端用于服务发现,一个Ribbon自己的组件,一个springboot-web依赖。
1.2 创建springboot启动类
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {
@Bean
@LoadBalanced
public RestTemplate template() {
return new RestTemplate();
}
public static void main(String[] args) {
new SpringApplicationBuilder(RibbonConsumerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
四个注解,一个Springboot启动注解,一个Eureka服务发现客户端注解,一个Spring容器管理注解,一个启用Ribbon负载均衡注解。因为Ribbon配合RestTemplate才能实现远程调用服务,所以在启动类中将RestTemplate纳入Spring管理,方便Autowired。
1.3 创建服务消费者controller
@RestController
public class Controller {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/sayHi")
public String sayHi() {
return restTemplate.getForObject("http://eureka-client/sayHi",String.class);
}
}
三个注解,一个Restful Controller注解,一个Spring自动注入注解,一个请求方法控制注解(restful规范),
1.4 修改配置文件
spring.application.name=ribbon-consumer
server.port=31000
eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/
配置服务名称,端口号,Eureka地址,配置完成,依次启动服务中心,消费者服务,即可实现调用。
2.负载均衡策略配置
2.1 配置全局负载均衡策略,创建Configuration配置类
@Configuration
public class RibbonConfiguration {
@Bean
public IRule defaultLBStrategy() {
return new RandomRule();
}
}
Configuration注解用于将当前类加入Spring上下文,Bean注解将Bean纳入Spring管理,IRule为Ribbon负载均衡策略*接口,其默认实现类为AbstractLoadBalancerRule:
博主springcloud版本为Greenwich.SR1版本,可以看到Ribbon提供了七种实现:
BestAvailableRule:在过滤掉故障服务后,它会基于过去30分钟的统计结果选取当前并发量最小的服务节点,也就是最“闲”的节点作为目标地址。如果统计结果尚未生成,则采用轮询的方式选定节点
ZoneAvoidanceRule: 包含了组合过滤条件,分别是Zone级别和可用性级别,Zone级别过滤为在Eureka注册中一个服务节点有Zone, Region和URL三个身份信息,其中Zone可以理解为机房大区(未指定则由Eureka给定默认值),而这里会对这个Zone的健康情况过滤其下面所有服务节点。可用性级别过滤和AvailabilityFilteringRule的验证非常像,会过滤掉当前并发量较大,或者处于熔断状态的服务节点
AvailabilityFilteringRule:这个规则底层依赖RandomRobinRule来选取节点,但并非来者不拒,必须要满足它的最低要求的节点才会被选中(节点处于非熔断状态和当前活跃请求数量不能超过阈值)。如果节点满足了要求,无论其响应时间或者当前并发量是什么,都会被选中
WeightedResponseTimeRule:这个Rule继承自RoundRibbonRule,他会根据服务节点的响应时间计算权重,响应时间越长权重就越低,响应越快则权重越高,权重的高低决定了机器被选中概率的高低。也就是说,响应时间越小的机器,被选中的概率越大
ResponseTimeWeightedRule:作用同 WeightedResponseTimeRule,ResponseTime-Weighted Rule 后来改名为 WeightedResponseTimeRule
RoundRobinRule:轮询选择,轮询 index,选择 index 对应位置的 Server
RandomRule:随机选择一个 Server
RetryRule:对选定的负载均衡策略机上重试机制,也就是说当选定了某个策略进行请求负载时在一个配置时间段内若选择 Server 不成功,则一直尝试使用 subRule 的方式选择一个可用的 Server
2.2 为单个服务配置负载均衡
方式一:配置文件方式
eureka-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
格式:ServiceName+ribbon.NFLoadBalancerRuleClassName = 上文中提到的类的全路径名
方式二:注解方式,在RibbonConfiguration配置类上新增一个注解
@RibbonClient(name = "eureka-client", configuration = com.netflix.loadbalancer.RoundRobinRule.class)
注:这里有一个小坑需要注意,如果同时应用了以上两种方式去配置负载均衡,注解的优先级更高,因为配置文件的加载顺序在注解之前,后加载的配置会覆盖先前配置。
3.饥饿加载配置
3.1 Ribbon的懒加载
Ribbon是在第一次方法调用的时候才去初始化LoadBalancer。这样看来,第一个方法请求不仅仅包含HTTP连接和方法的响应时间,还包括了LoadBalancer的创建耗时。假如你的方法本身就比较耗时的话,而且超时时间又设置的比较短,那么很大可能这第一次http调用就会失败。其实还有很多框架也实现了类似的懒加载功能,比如Hibernate的lazy-fetch,懒加载在大部分情况下可以节省系统资源开销,但某些情况下反而导致服务响应时间被延长。
3.2 Ribbon饥饿加载配置
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=ribbon-demo
ribbon.eager-load.enabled:开启Ribbon的饥饿加载模式。
ribbon.eager-load.clients:指定需要饥饿加载的服务名,若有多个则用逗号隔开。
4.常用配置
4.1 禁用Eureka
毕竟Ribbon不是Spring官方出的,如果就想禁用Eureka呢?
# 禁用 Eureka
ribbon.eureka.enabled=false
当我们禁用了 Eureka 之后,就不能使用服务名称去调用接口了,必须指定服务地址。
4.2 配置接口地址列表
禁用Eureka后需要手动配置调用的服务地址
# 禁用 Eureka 后手动配置服务地址
ribbon-config-demo.ribbon.listOfServers=localhost:8081,localhost:8083
4.3 配置并发参数
# 最大连接数
ribbon.MaxTotalConnections=500
# 每个host最大连接数
ribbon.MaxConnectionsPerHost=500
4.4 配置超时参数
Ribbon中有两种和时间相关的设置,分别是请求连接的超时时间和请求处理的超时时间,设置规则如下:
# 请求连接的超时时间
ribbon.ConnectTimeout=2000
# 请求处理的超时时间
ribbon.ReadTimeout=5000
也可以为每个Ribbon客户端设置不同的超时时间, 通过服务名称进行指定:
ribbon-config-demo.ribbon.ConnectTimeout=2000
ribbon-config-demo.ribbon.ReadTimeout=5000
ConnectTimeout:创建会话的连接时间,注意,不是服务的响应时间,而是本机与服务建立会话的时间。
ReadTimeout:当连接建立好之后,如果对方服务没有在规定时间内返回,则直接进行重试。
4.5 配置重试机制,并计算最大超时时间
#不指定Ribbon默认使用轮询进行重试
feign-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RetryRule
# 在所有HTTP Method进行重试
feign-client.ribbon.OkToRetryOnAllOperations=true
# 每台机器最大重试次数
feign-client.ribbon.MaxAutoRetries=2
# 可以再重试几台机器
feign-client.ribbon.MaxAutoRetriesNextServer=2
最大超时时间计算公式:MAX(Response Time) = (ConnectTimeout + ReadTimeout) * (MaxAutoRetries + 1) * (MaxAutoRetriesNextServer + 1)