文章目录
五、Netflix Ribbon 负载均衡
5.1 Ribbon 简介
Netflix Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST请求自动转换成客户端负载均衡的服务调用。微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的;
Ribbon的主要作用就是两个:
1)服务之间调用
2)服务调用时的负载均衡
5.2 Ribbon 快速入门
5.2.1 Ribbon 服务负载均衡
Ribbon已经被被集成到Eureka中,我们之前在学习Eureka时就已经用过了Ribbon了;
在RestTemplate上添加@LoadBalanced注解之后,调用接口便自动继承了负载均衡的能力;
- ItemApplication:
package com.cloud.item;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* @author lscl
* @version 1.0
* @intro:
*/
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现功能
@EnableEurekaClient // 开启Eureka客户端
public class ItemApplication {
public static void main(String[] args) {
SpringApplication.run(ItemApplication.class);
}
@Bean
@LoadBalanced // 负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
- ItemController:
package com.cloud.item.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
/**
* @author lscl
* @version 1.0
* @intro:
*/
@RestController
@RequestMapping("/item")
public class ItemController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/findOrderById/{orderId}")
public Map findOrderById(@PathVariable Integer orderId){
// 使用RestTemplate进行远程调用
Map resultMap = restTemplate.getForObject("http://order-service/order/" + orderId, Map.class);
return resultMap;
}
}
- OrderController:
/**
* @author lscl
* @version 1.0
* @intro:
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Value("${server.port}")
private String port;
@GetMapping("{id}")
public Map findById(@PathVariable Integer id){
return new HashMap(){{
put("flag",true);
put("message","查询成功"+ip+":"+port);
put("statusCode","200");
put("id",id);
}};
}
}
启动两个Order服务,访问:http://localhost:9001/item/findOrderById/1
多次访问,查看是否有轮询效果;
5.2.2 自定义服务列表
当我们在 RestTemplate
上添加 @LoadBalanced
注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。这是因为 Eureka 中的服务信息已经被拉取到了客户端本地,关系如下:
有的时候我们希望Ribbon可以跳过Eureka,直接使用IP+端口的方式调用服务,这样的我们就不需要借助Eureka提供的服务名来远程调用了(测试环境用),我们可以自定义服务列表来实现负载均衡;
关闭Ribbon与Eureka的集成:
ribbon:
eureka:
enabled: false # 关闭与Eureka的集成
ribbon-order-service: # 自定义服务名称
ribbon:
listOfServers: localhost:9001,localhost:9002 # 服务的主机列表
注意:默认情况下Ribbon与Eureka的集成为开启状态,在开启状态下,只能使用服务名调用;而在关闭状态下,只能使用IP+端口来调用,如果指定IP+端口的方式来调用,那么必定不能提供负载均衡的功能;如果想使用负载均衡功能,那么必须自定义服务名称,并为该服务配置主机列表;
- ItemController:
@GetMapping("/findOrderById/{orderId}")
public Map findOrderById(@PathVariable Integer orderId){
// 使用自定义的服务名称
Map resultMap = restTemplate.getForObject("http://ribbon-order-service/order/" + orderId, Map.class);
return resultMap;
}
- OrderController:
package com.cloud.order.controller;
import com.cloud.order.entity.Order;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author lscl
* @version 1.0
* @intro:
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Value("${server.port}")
private String port;
@GetMapping("{id}")
public Map findById(@PathVariable Integer id) {
return new HashMap() {{
put("flag", true);
put("message", "查询成功" + ip + ":" + port);
put("statusCode", "200");
put("id", id);
}};
}
}
5.3 Ribbon的配置
5.3.1 Ribbon 的属性配置
Ribbon的所有的默认配置可以去com.netflix.client.config.DefaultClientConfigImpl
类下找:
关于Ribbon的所有配置在com.netflix.client.config.CommonClientConfigKey
中定义:
5.3.2 Ribbon常用配置
5.3.2.1 连接配置
ribbon:
ConnectTimeout: 2000 # 请求连接的超时时间
ReadTimeout: 5000 # 请求处理的超时时间
ConnectTimeout:是指请求发送到服务,两端连接所需要的时间
ReadTimeout:是指建立连接后从服务端读取到可用资源所用的时间
5.3.2.2 懒加载配置
Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易出现第一次调用超时,之后就调用正常的现象;
ribbon:
eager-load:
enabled: true # 开启立即加载客户端
clients: ribbon-order-service,ribbon02-order-service # 选择指定的服务开启立即加载
5.3.2.3 并发调整
ribbon:
MaxTotalConnections: 500 # 最大连接数
MaxConnectionsPerHost: 100 # 每个host最大连接数
5.3.3 Ribbon 配置策略
Ribbon的配置分为全局配置和指定客户端配置,两种配置格式不同;
全局配置针对于所有的服务,客户端配置只针对于具体服务使用;
- 全局配置:
ribbon:
ConnectTimeout: 20000 # 请求连接的超时时间
ReadTimeout: 5000 # 请求处理的超时时间
- 客户端配置:
ribbon-order-service: # 自定义服务名称
ribbon:
listOfServers: localhost:9001,localhost:9002 # 服务的主机列表
ConnectTimeout: 20000
ReadTimeout: 5000
Tips:全局配置只针对集成Eureka时的调用,不能作用于自定义微服务名称调用;
5.4 Ribbon的负载均衡策略
5.4.1 Ribbon负载均衡策略
不难发现,我们之前使用Ribbon的负载均衡策略都是轮询;在Ribbon中,除了轮询策略外,还提供有其他几种策略,内部负责负载均衡的顶级接口为com.netflix.loadbalancer.IRule
:
-
com.netflix.loadbalancer.RoundRobinRule
:- **轮询策略;**以轮询的方式进行负载均衡。
-
com.netflix.loadbalancer.WeightedResponseTimeRule
:- **权重策略;**会计算每个服务的权重,响应速度越快的实例选择权重越大,越高的被调用的可能性越大。
-
com.netflix.loadbalancer.ResponseTimeWeightedRule
:- **权重策略;**作用和WeightedResponseTimeRule一致,后来改名为 WeightedResponseTimeRule
-
com.netflix.loadbalancer.BestAvailableRule
:- **最佳策略;**首先过滤掉故障实例,在没有故障的实例中,选择一个压力最小(并发量)的服务
-
com.netflix.loadbalancer.ZoneAvoidanceRule
:- **回避策略;**使用 ZoneAvoidancePredicate 和 AvailabilityPredicate 来判断是否选择某个 Server,前一个判断判定一个 Zone 的运行性能是否可用,剔除不可用的 的所有 Server,AvailabilityPredicate 用于过滤掉连接数过多的 Server。
-
com.netflix.loadbalancer.AvailabilityFilteringRule
:- **过滤策略;**过滤掉故障和请求数超过阈值的服务实例,再从剩下的实例中轮询调用。
-
com.netflix.loadbalancer.RandomRule
:- **随机策略;**在服务列表中随机选择一个服务调用;
-
com.netflix.loadbalancer.RetryRule
:- **重试策略;**在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内服务未响应,则继续使用轮询方式访问其他服务;
5.4.1 修改Ribbon负载均衡策略
- 配置文件方式修改负载均衡策略:基于自定义服务名调用
ribbon:
eureka:
enabled: false # 关闭与Eureka的集成
ribbon-order-service: # 只修改ribbon-order-service这个服务的负载均衡策略
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 随机策略
listOfServers: localhost:9001,localhost:9002,localhost:9003 # 服务的主机列表
- 基于Eureka服务名调用:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
- 配置类方式修改负载均衡策略:
/**
* 随机策略
* @return
*/
@Bean
public RandomRule randomRule(){
return new RandomRule();
}
tips:同时指定了配置文件和类的方式时,以加载的负载均衡类为准;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131748.html