• spring cloud新版本使用loadbalancer替代Ribbon


    Nacos 2021 不再集成 Ribbon,建议使用spring cloud loadbalancer
    引入

    一、简单使用

    引入依赖spring cloud loadbalancer

    1. <dependency>
    2. <groupId>org.springframework.cloud</groupId>
    3. <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    4. </dependency>

    RestTemplate集成

    启动类的restTemplate bean方法添加@LoadBalanced注解

    1. @Bean
    2. @LoadBalanced
    3. public RestTemplate restTemplate(){
    4. return new RestTemplate();
    5. }

    二、修改默认负载均衡方式

    Spring Cloud Balancer中实现了轮询RoundRobinLoadBalancer和随机数RandomLoadBalancer两种负载均衡算法

    默认情况下的负载均衡为轮询RoundRobinLoadBalancer

    如果我们需要改成随机RandomLoadBalancer,可以自定义

    新建文件 CustomLoadBalancerConfiguration.java

    1. package com.itmuch.contentcenter.rule;
    2. import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
    3. import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
    4. import org.springframework.cloud.client.ServiceInstance;
    5. import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
    6. import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
    7. import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
    8. import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
    9. import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
    10. import org.springframework.context.annotation.Bean;
    11. import org.springframework.context.annotation.Configuration;
    12. import org.springframework.core.env.Environment;
    13. @Configuration
    14. public class CustomLoadBalancerConfiguration {
    15. @Bean
    16. ReactorLoadBalancer<ServiceInstance> loadBalancer(Environment environment,
    17. LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties) {
    18. String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    19. //轮询加载,默认就是这个
    20. /*return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
    21. ServiceInstanceListSupplier.class),name);*/
    22. //返回随机轮询负载均衡方式
    23. return new RandomLoadBalancer(loadBalancerClientFactory.
    24. getLazyProvider(name, ServiceInstanceListSupplier.class),
    25. name);
    26. //nacos的负载均衡策略,按权重分配
    27. /*return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
    28. ServiceInstanceListSupplier.class),
    29. name, nacosDiscoveryProperties);*/
    30. }
    31. }

    然后在启动类加注解@LoadBalancerClient,参数name为spring.application.name,configuration为上面自定义的类

    1. package com.itmuch.contentcenter;
    2. import com.itmuch.contentcenter.rule.CustomWeightLoadBalancerConfiguration;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    6. import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
    7. import org.springframework.context.annotation.Bean;
    8. import org.springframework.web.client.RestTemplate;
    9. import tk.mybatis.spring.annotation.MapperScan;
    10. // 扫描mybatis哪些包里面的接口
    11. @MapperScan("com.itmuch")
    12. @SpringBootApplication
    13. @LoadBalancerClient(name = "user-center",configuration = CustomLoadBalancerConfiguration.class)
    14. public class ContentCenterApplication {
    15. public static void main(String[] args) {
    16. SpringApplication.run(ContentCenterApplication.class, args);
    17. }
    18. //在spring容器装载哪一个对象,类型为RestTemplate 名称为restTemplate
    19. //
    20. @Bean
    21. @LoadBalanced
    22. public RestTemplate restTemplate(){
    23. return new RestTemplate();
    24. }
    25. }

    三、自定义负载均衡策略

    如果我们想自定义策略。可以参考RoundRobinLoadBalancer类自己实现

    以下为调3次轮换的自定义策略

    CustomWeightLoadBalancerConfiguration.java

    1. package com.itmuch.contentcenter.rule;
    2. import org.springframework.cloud.client.ServiceInstance;
    3. import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
    4. import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
    5. import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
    6. import org.springframework.context.annotation.Bean;
    7. import org.springframework.context.annotation.Configuration;
    8. import org.springframework.core.env.Environment;
    9. @Configuration
    10. public class CustomWeightLoadBalancerConfiguration {
    11. @Bean
    12. ReactorLoadBalancer weightloadBalancer(Environment environment,
    13. LoadBalancerClientFactory loadBalancerClientFactory) {
    14. String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    15. //返回自定义负载均衡方式
    16. return new WeightLoadBalancer(loadBalancerClientFactory.
    17. getLazyProvider(name, ServiceInstanceListSupplier.class),
    18. name);
    19. }
    20. }

    WeightLoadBalancer.java

    核心在于重载实现ReactorServiceInstanceLoadBalancer类的choose方法

    1. package com.itmuch.contentcenter.rule;
    2. import org.apache.commons.logging.Log;
    3. import org.apache.commons.logging.LogFactory;
    4. import org.springframework.beans.factory.ObjectProvider;
    5. import org.springframework.cloud.client.ServiceInstance;
    6. import org.springframework.cloud.client.loadbalancer.DefaultResponse;
    7. import org.springframework.cloud.client.loadbalancer.EmptyResponse;
    8. import org.springframework.cloud.client.loadbalancer.Request;
    9. import org.springframework.cloud.client.loadbalancer.Response;
    10. import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
    11. import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
    12. import reactor.core.publisher.Mono;
    13. import java.util.List;
    14. public class WeightLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    15. private static final Log log = LogFactory.getLog(WeightLoadBalancer.class);
    16. private int total = 0; // 被调用的次数
    17. private int index = 0; // 当前是谁在提供服务
    18. private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
    19. private String serviceId;
    20. public WeightLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {
    21. this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    22. this.serviceId = serviceId;
    23. }
    24. @Override
    25. public Mono<Response<ServiceInstance>> choose(Request request) {
    26. ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
    27. return supplier.get().next().map(this::getInstanceResponse);
    28. }
    29. //每个服务访问3次,然后换下一个服务
    30. private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
    31. log.info("进入自定义负载均衡");
    32. if (instances.isEmpty()) {
    33. return new EmptyResponse();
    34. }
    35. log.info("每个服务访问3次后轮询");
    36. int size = instances.size();
    37. ServiceInstance serviceInstance = null;
    38. while (serviceInstance == null) {
    39. System.out.println("===");
    40. if (total < 3) {
    41. serviceInstance = instances.get(index);
    42. total++;
    43. } else {
    44. total = 0;
    45. index++;
    46. if (index >= size) {
    47. index = 0;
    48. }
    49. serviceInstance = instances.get(index);
    50. }
    51. }
    52. return new DefaultResponse(serviceInstance);
    53. }
    54. }

    最后跟上面一样,启动类加注解@LoadBalancerClient,指向自定义的config

    @LoadBalancerClient(name = "user-center",configuration = CustomWeightLoadBalancerConfiguration.class)
    

    四、使用nacos的负载均衡策略

    在nacos定义了负载均衡策略类NacosLoadBalancer,我们可以直接使用

    使用配置类方式

    1. package com.itmuch.contentcenter.rule;
    2. import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
    3. import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
    4. import org.springframework.cloud.client.ServiceInstance;
    5. import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
    6. import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
    7. import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
    8. import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
    9. import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
    10. import org.springframework.context.annotation.Bean;
    11. import org.springframework.context.annotation.Configuration;
    12. import org.springframework.core.env.Environment;
    13. @Configuration
    14. public class CustomLoadBalancerConfiguration {
    15. @Bean
    16. ReactorLoadBalancer loadBalancer(Environment environment,
    17. LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties) {
    18. String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    19. //nacos的负载均衡策略,按权重分配
    20. return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
    21. ServiceInstanceListSupplier.class),
    22. name, nacosDiscoveryProperties);
    23. }
    24. }

    然后还是启动类加注解@LoadBalancerClient,指向自定义的config

    @LoadBalancerClient(name = "user-center",configuration = CustomLoadBalancerConfiguration.class)

    配置文件方式

    1. #开启nacos的负载均衡策略
    2. spring.cloud.loadbalancer.nacos.enabled=true

    如果需要根据nacos的权重进一步自定义,可参考NacosLoadBalancer的代码自己实现

    可参考Nacos负载均衡策略_nacos负载均衡策略配置_carroll18的博客-CSDN博客

  • 相关阅读:
    【笔记篇】11仓管系统WCS系统——之《实战供应链》
    中级经济师(经济基础知识)第一章 社会主义基本经济制度
    策略模式、策略模式与工厂模式相结合
    ubuntu 安装 gnome 安装 xrdp
    TCP缓存
    CentOS7 下载安装卸载 Docker——Docker启动关闭
    【Oracle】Oracle系列之十四--触发器
    电脑多开微信教程,可以多开n个
    Docker面试题库
    checkbox 设置默认值
  • 原文地址:https://blog.csdn.net/gsls200808/article/details/132603527