Ribbon是SpringCloud体系中用来实现负载均衡的组件,通常来说,它不是一个独立的组件,而是存在于各个微服务上的。
负载均衡一般分为两种:
- 服务器端负载均衡,比如Nginx,是一台独立的服务器作为应用服务的前置,反向代理实现服务集群的负载均衡。
- 客户端负载均衡,比如Ribbon,是进程级别的,存在于各个Consumer微服务上的负载均衡机制。
一、项目准备
本文是在如下这篇Eureka入门案例的基础上扩展实现的,所以,要先按照如下的文章先搭建好Eureka的服务端和客户端。
有了上述案例的代码后,我们从start.spring.io
上一键下载一个自带Eureka-client
和Ribbon
的工程,命名为ribbon-demo
,并做如下内容的修改。
1.1 启动类
@SpringBootApplication
@EnableEurekaClient
public class RibbonDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonDemoApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
- Ribbon客户端本身作为一个Eureka客户端存在,因此需要
@EnableEurekaClient
注解,并且向注册中心注册服务; -
@Bean
和@LoadBalanced
注解是注入一个RestTemplate实例,并标明是负载均衡使用的;
1.2 配置文件
作为一个Eureka客户端,我们仍然需要如下的配置信息,以保证注册服务到注册中心服务器上。
server.port=8090
# 当前应用名称
spring.application.name=ribbon-client
# eureka注册中心地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
1.3 创建一个Rest请求类
我们打算对外暴露一个接口,接收来自浏览器的请求,然后将这些请求以负载均衡的方式发送给真正的服务端。
@RestController
public class RibbonTestController {
private static String EUREKA_URL = "http://eureka-client/getHello";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getRibbonHello")
public String getRibbonHello(HttpServletRequest request){
String result = restTemplate.getForObject(EUREKA_URL, String.class);
System.out.println(result);
return result;
}
}
如此,我们就准备好了一个最简单的Ribbon案例。
二、入门实例
现在我们有了如下这些服务:
-
Eureka服务端,在8761端口提供服务;
-
Eureka客户端A,在8088端口提供服务;
对其中的Rest请求案例稍作修改:
@RestController public class RibbonTestController { @GetMapping("/getHello") public String getRibbonHello(HttpServletRequest request){ return "From port:" + request.getServerPort(); } }
-
Eureka客户端B,在8089端口提供服务,除了启动端口外其余内容和客户端A一样;
-
Ribbon客户端,在8090端口提供服务;
现在,我们按照如上顺序启动所有的服务,访问注册中心控制台,就能看到这些服务。
启动ribbon客户端后的eureka控制台我们开始多次请求Ribbon客户端的接口http://localhost:8090/getRibbonHello
,就会发现,Ribbon客户端是在默认采用轮询的方式对所有名称为eureka-client
的服务发起请求并返回接口给浏览器。
三、Ribbon配置
3.1 负载均衡策略
- 轮询RoundRobinRule,这也是默认的策略;
- 随机RandomRule
- 响应时间权重ResponseTimeWeightedRule,为每个服务设置权重,响应时间越短,权重越大,下次越有可能被选中;
- 最少并发数策略BestAvailableRule
- 重试策略RetryRule
- 可用性敏感策略AvailabilityFilteringRule
- 区域性敏感策略ZoneAvoidanceRule
总共有七种负载均衡策略可供选择,可以根据自己的业务场景进行选择。
默认情况下,系统采用的是轮询策略,那么如何通过配置来更换负载均衡策略呢?
方法一、增加一个配置类
@Configuration
public class RibbonBalancedStrategyConfig {
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
该配置类对全局Ribbon生效,当我们再次重启Ribbon客户端的时候,多次访问http://localhost:8090/getRibbonHello
就会得到如下的随机结果。
方法二、使用配置文件
有时候,我们Ribbon可能会负载均衡多个服务源,对于某个服务源我们想更改负载均衡策略,而不是全部,那么就可以在配置文件中进行配置。
# 指定eureka-client服务源的负载均衡策略
eureka-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
同样的,我们多次访问得到的也是随机负载的策略效果。
3.2 超时与重试
同样的,在配置文件中进行配置即可。
eureka-client.ribbon.ConnectTimeout=1
eureka-client.ribbon.ReadTimeout=1
eureka-client.ribbon.MaxAutoRetries=1
eureka-client.ribbon.MaxAutoRetriesNextServer=1
eureka-client.ribbon.OkToRetryOnAllOperations=true
3.3 饥饿加载
我们的ribbon-client客户端在启动的时候并不会立即加载上下文,需要在请求真正到来时才会创建,如此会有可能导致第一次调用某个服务源的时候出现很慢的情况,我们可以通过如下配置项的方式来指定具体的服务名称开启饥饿加载,即在启动的时候就加载所有服务应用上下文。
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=eureka-client,eureka-client2
网友评论