SpringCloudAlibaba - 扩展 Ribbon支持 Nacos 权重
前言
Nacso
可以为每一个实例配置权重,权重越大代表该实例被调用的几率越大,Ribbon
内置的负载均衡规则并不支持Nacos
的权重,需要额外扩展
环境
Spring Cloud Hoxton.SR9 + Spring Cloud Alibaba 2.2.6.RELEASE + Nacos 1.4.2
测试用例
用户中心 user-center
TestController.java
@RestController
@Slf4j
public class TestController {
@GetMapping("/test/{name}")
public String test(@PathVariable String name) {
log.info("请求...");
return "hello " + name;
}
}
内容中心 content-center
TestController.java
@GetMapping("test3")
public String test3() {
return restTemplate.getForObject(
"http://user-center/test/{name}",
String.class,
"Coisini"
);
}
默认的负载均衡
- 用户中心启动两个实例,端口为
8081
,8082
,默认情况下,两个实例的权重都为1
,访问分布平均
具体实现
代码配置
NacosWeightedRule.java
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description Nacos权重负载均衡
*/
@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
/**
* 读取配置文件,并初始化 NacosWeightedRule
* @param iClientConfig
*/
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
/**
* 权重负载均衡实现
* @param o
* @return
*/
@Override
public Server choose(Object o) {
try {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
// 想要请求的微服务的名称
String name = loadBalancer.getName();
// 拿到服务发现的相关API
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
// NacosClient通过基于权重的负载均衡算法来选择一个实例。
Instance instance = namingService.selectOneHealthyInstance(name);
log.info("实例:port = {}, instance = {}", instance.getPort(), instance);
return new NacosServer(instance);
} catch (NacosException e) {
return null;
}
}
}
RibbonConfiguration.java
import com.coisini.contentcenter.configuration.NacosWeightedRule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description Ribbon的配置类
*/
@Configuration
public class RibbonConfiguration {
/**
* 自定义负载均衡规则
* NacosWeightedRule Nacos权重
* @return
*/
@Bean
public IRule ribbonRule() {
return new NacosWeightedRule();
}
}
UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;
/**
* @Description 用户中心配置类
*/
@Configuration
@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
测试
-
重启应用
-
修改
8082
端口实例的权重为0
(Nacos
权重值为0-1
,权重越大代表该实例被调用的几率越大)
- 访问测试接口可以看到,访问都集中在权重较高的实例
8081
上
项目源码
GitHub
: https://github.com/Maggieq8324/coisini-cloud-alibabaGitee
: https://gitee.com/maggieq8324/coisini-cloud-alibaba