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"
    );
}

默认的负载均衡

  • 用户中心启动两个实例,端口为80818082,默认情况下,两个实例的权重都为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端口实例的权重为0Nacos权重值为0-1,权重越大代表该实例被调用的几率越大)

在这里插入图片描述

  • 访问测试接口可以看到,访问都集中在权重较高的实例8081

在这里插入图片描述


项目源码



- End -
白嫖有风险
点赞加收藏
posted @ 2021-09-23 00:38  Maggieq8324  阅读(240)  评论(0编辑  收藏  举报