[梦中一夜下江南总结]SpringBoot集成负载匀衡Ribbon以及相关的配置

第一步添加依赖

如果添加过

<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
       <version>0.2.2.RELEASE</version>
</dependency>

无需依赖

第二步写注解 @LoadBalanced

在RestTemplate的ioc上面写一下

代码如下

    //在容器中,创建一个对象
    @Bean   //这是Spring的注解,可以在相关的页面自动注入。
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

Ribbon自带整合发现。所以上一章节的DiscoveryClient就不需要了。替换代码如下,

原来的


private final DiscoveryClient discoveryClient;

	discoveryClient.getInstances("user-center");

现在的

this.restTemplate.getForObject(
                "http://user-center/users/{id}",
                UserDTO.class,
                userId);
//user-center 为模块名称,自动实现负载均衡。

这就使用好了

以下是配置的总结,也就是根据实际需求来定制负载的请求。

首先讲一下java代码配置

第一步

新建一个包、路径为com.liuyun.contentcenter.configuration
新建一个类 UserCenterRibbonConfiguration.java

内容如下:可以直接复制使用。


@Configuration
@RibbonClient(configuration = RibbonConfiguration.class) //不是全局的配置。
@RibbonClients(defaultConfiguration = RibbonConfiguration.class) // 是全局的配置。
public class UserCenterRibbonConfiguration {

}

RibbonConfiguration  //这个类在下面配置

第二步

新建一个包、路径为main/java/ribbonconfiguration/
新建一个类 RibbonConfiguration.java 注意这个类不在com 包下面,这样做是为了配置冲突。

内容如下:可以直接复制使用。

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
}

也可以继承相关类IRule等等实现自定义规则

拓展: 实现Ribbon支持nacos的权重,代码如下

@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {

	//
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;


    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
        //读取配置文件
    }

    @Override
    public Server choose(Object o) {
        try {
            BaseLoadBalancer loadBalancer = (BaseLoadBalancer)this.getLoadBalancer();

			//想要请求的微服务名称
            String name = loadBalancer.getName();
			
			//实现服务发现的相关api
            NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();

			//nacos server自动实现基于权重的算法。
            Instance instance = namingService.selectOneHealthyInstance(name);

            log.info("port = {} , instance = {}" ,instance.getPort(),instance);

			//通过NacosServer可以把Instance转换成Server
            return new NacosServer(instance);
        } catch (NacosException e) {
            e.printStackTrace();

            return null;
        }


    }
}

在下面配置

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule ribbonRule(){
        return new NacosWeightedRule();
    }
}

以下代码是扩展Ribbon:支持Nacos同集群优先调用的配置

可以在application.yml文件里面加入。

spring:
  cloud:
    nacos:
        metadata: 
          # 自己这个实例的版本
          version: v1
          # 允许调用的提供者版本
          target-version: v1

在调用者的代码里面配置。

@Slf4j
public class NacosFinalRule extends AbstractLoadBalancerRule {
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public Server choose(Object key) {
        // 负载均衡规则:优先选择同集群下,符合metadata的实例
        // 如果没有,就选择所有集群下,符合metadata的实例

        // 1. 查询所有实例 A
        // 2. 筛选元数据匹配的实例 B
        // 3. 筛选出同cluster下元数据匹配的实例 C
        // 4. 如果C为空,就用B
        // 5. 随机选择实例
        try {
            String clusterName = this.nacosDiscoveryProperties.getClusterName();
            String targetVersion = this.nacosDiscoveryProperties.getMetadata().get("target-version");

            DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
            String name = loadBalancer.getName();

            NamingService namingService = this.nacosDiscoveryProperties.namingServiceInstance();

            // 所有实例
            List<Instance> instances = namingService.selectInstances(name, true);

            List<Instance> metadataMatchInstances = instances;
            // 如果配置了版本映射,那么只调用元数据匹配的实例
            if (StringUtils.isNotBlank(targetVersion)) {
                metadataMatchInstances = instances.stream()
                        .filter(instance -> Objects.equals(targetVersion, instance.getMetadata().get("version")))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(metadataMatchInstances)) {
                    log.warn("未找到元数据匹配的目标实例!请检查配置。targetVersion = {}, instance = {}", targetVersion, instances);
                    return null;
                }
            }

            List<Instance> clusterMetadataMatchInstances = metadataMatchInstances;
            // 如果配置了集群名称,需筛选同集群下元数据匹配的实例
            if (StringUtils.isNotBlank(clusterName)) {
                clusterMetadataMatchInstances = metadataMatchInstances.stream()
                        .filter(instance -> Objects.equals(clusterName, instance.getClusterName()))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(clusterMetadataMatchInstances)) {
                    clusterMetadataMatchInstances = metadataMatchInstances;
                    log.warn("发生跨集群调用。clusterName = {}, targetVersion = {}, clusterMetadataMatchInstances = {}", clusterName, targetVersion, clusterMetadataMatchInstances);
                }
            }

            Instance instance = ExtendBalancer.getHostByRandomWeight2(clusterMetadataMatchInstances);
            return new NacosServer(instance);
        } catch (Exception e) {
            log.warn("发生异常", e);
            return null;
        }
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
}

负载均衡的算法,是上面类的 ExtendBalancer

public class ExtendBalancer extends Balancer {
    /**
     * 根据权重,随机选择实例
     *
     * @param instances 实例列表
     * @return 选择的实例
     */
    public static Instance getHostByRandomWeight2(List<Instance> instances) {
        return getHostByRandomWeight(instances);
    }
}

下面是配置文件方式的配置。

第一种是默认的轮询策略 RoundRobinRule

第二种是 RandomRule(随机策略) 可以在application.yml文件里面加入。

ribbon:
  eager-load:
    enabled: true
    clients: user-center
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

其实如果公司不大的话,普通的配置足以应付日常的负载了,推荐使用配置文件配置。一下是相关配置的key

NFLoadBalancerClassName
NFLoadBalancerRuleClassName   IRule子类
NFLoadBalancerPingClassName   IPing子类
NIWSServerListClassName
NIWSServerListFilterClassName
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值