一. 负载均衡分类
- 服务端负载均衡:
最经典的例如:Nginx
用户的请求先发到nginx,再由nginx 负载均衡算法后分发到适合的服务器,由于Nginx需要作为一个服务部署在服务器端,所以称之为服务端负载均衡
- 客户端负载均衡:
由发送请求的客户端来实现负载均衡的方式称为客户端负载均衡,常应用于微服务架构应用中,例如Spring Cloud 的 Netflix 的一个开源的客户端负载均衡器
客户端负载均衡的好处就是不用再经过一个负载均衡服务器,可以直接去调用服务,可以提高一定的性能和可用性
调用原理:
微服务A 调用微服务B- 微服务A利用服务发现组件去获取微服务B的所有实例地址
- 微服务A利用客户端的负载均衡算法去选取一个合适的微服务B的地址进行调用
二. 客户端负载均衡的Ribbon实现
Ribbon:
1. Ribbon是SpringCloud Netflix子项目的一个开源组件
2. Ribbon内置了八种 负载均衡算法
Ribbon 内置接口:
Ribbon默认内置了八种负载均衡策略,若想自定义负载均衡策略则实现上表中提到的IRule接口或AbstractLoadBalancerRule抽象类即可。内置的负载均衡策略如下:
**默认的策略规则为ZoneAvoidanceRule,类似于轮询策略
Ribbon的 使用方式:
1. Feign 默认整合Ribbon
2. RestTemplate 结合@LoadBalanced 以及Ribbon依赖(nacos依赖中已经包含) 使用
自定义负载均衡策略:
两种方式:
1. 代码实现
2. 配置文件实现
一. 代码实现:
1. 只针对某个服务自定义负载均衡
1.1. 编写一个配置类,用于实例化 需要的负载均衡策略对象
@Configuration
public class RibbonConfig {
@Bean
public IRule ribbonRule(){
// 随机的负载均衡策略对象(可指定需要的负载均衡策略对象)
return new RandomRule();
}
}
1.2. 编写一个用于配置Ribbon客户端的配置类 ,用于指定调用哪个微服务时采用自定义的负载均衡策略
@Configuration
// 该注解用于自定义Ribbon客户端配置,这里声明为属于user-center的配置
@RibbonClient(name = "要调用的微服务", configuration = RibbonConfig.class)
public class UserCenterRibbonConfig {
}
优点:可以达到细粒度的定义负载均衡策略
注意事项:RibbonConfig 自定义负载均衡配置类得放在 启动类外面,不能让spring扫描到
要是让spring扫描到,那么就会变成全局配置,所有的调用服务都会采用这种负载均衡策略对象
二. 配置实现:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
以上是细粒度的负载均衡策略配置方式
还有全局的负载均衡配置方式:
将@RibbonClient(name = "要调用的微服务", configuration = RibbonConfig.class) 改为
@RibbonClients(defaultConfiguration = RibbonConfig.class)
@Configuration
//细粒度的负载均衡配置机制
//@RibbonClient(name = "要调用的微服务", configuration = RibbonConfig.class)
// 该注解用于全局配置
@RibbonClients(defaultConfiguration = RibbonConfig.class)
public class GlobalRibbonConfig {
}
关于 负载均衡策略配置方式的优先级:
细粒度配置文件配置 > 细粒度代码配置 > 全局配置文件配置 > 全局代码配置
Ribbon默认是懒加载的方式,所以第一次调用服务会比较慢,可以配置开启饥饿加载:
Ribbon默认是懒加载的,所以在第一次发生请求的时候会显得比较慢,我们可以通过在配置文件中添加如下配置开启饥饿加载:
ribbon:
eager-load:
enabled: true
# 为哪些客户端开启饥饿加载,多个客户端使用逗号分隔(非必须)
clients: user-center
三.配合nacos使用
- Ribbon内置负载均衡策略不支持nacos的权重,可自定义支持nacos权重
服务列表 -> 详情 -> 编辑;默认权重都为1,权重值越大就越优先被调用:
nacos的控制台可以编辑一个服务多个实例的权重,编辑页面如下:
可以通过权重配置来合理的分配客户端对微服务的调用请求,比如可以将机器性能差的微服务实例权重调低,减少对该实例的调用请求
由于Ribbon内置的负载均衡策略不支持nacos权重,所以必须自定义一个负载均衡策略支持权重:
/**
* 支持Nacos权重配置的负载均衡策略
*
* @author 01
* @date 2019-07-27
**/
@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties discoveryProperties;
/**
* 读取配置文件,并初始化NacosWeightedRule
*
* @param iClientConfig iClientConfig
*/
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
// do nothing
}
@Override
public Server choose(Object key) {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
log.debug("lb = {}", loadBalancer);
// 需要请求的微服务名称
String na