当前位置: 首页 > news >正文

spring cloud新版本使用loadbalancer替代Ribbon

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

一、简单使用

引入依赖spring cloud loadbalancer

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

RestTemplate集成

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

@Bean
@LoadBalanced
public RestTemplate restTemplate(){return new RestTemplate();
}

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

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

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

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

新建文件 CustomLoadBalancerConfiguration.java

package com.itmuch.contentcenter.rule;import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;@Configuration
public class CustomLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> loadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);//轮询加载,默认就是这个/*return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,ServiceInstanceListSupplier.class),name);*///返回随机轮询负载均衡方式return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);//nacos的负载均衡策略,按权重分配/*return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,ServiceInstanceListSupplier.class),name, nacosDiscoveryProperties);*/}
}

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

package com.itmuch.contentcenter;import com.itmuch.contentcenter.rule.CustomWeightLoadBalancerConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.spring.annotation.MapperScan;// 扫描mybatis哪些包里面的接口
@MapperScan("com.itmuch")
@SpringBootApplication
@LoadBalancerClient(name = "user-center",configuration = CustomLoadBalancerConfiguration.class)
public class ContentCenterApplication {public static void main(String[] args) {SpringApplication.run(ContentCenterApplication.class, args);}//在spring容器装载哪一个对象,类型为RestTemplate 名称为restTemplate// <bean id="restTemplate" clase ="xxx.xxx.RestTemplate"@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
}

三、自定义负载均衡策略

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

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

CustomWeightLoadBalancerConfiguration.java

package com.itmuch.contentcenter.rule;import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;@Configuration
public class CustomWeightLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> weightloadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);//返回自定义负载均衡方式return new WeightLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

WeightLoadBalancer.java

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

package com.itmuch.contentcenter.rule;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import reactor.core.publisher.Mono;import java.util.List;public class WeightLoadBalancer implements ReactorServiceInstanceLoadBalancer {private static final Log log = LogFactory.getLog(WeightLoadBalancer.class);private int total = 0;    // 被调用的次数private int index = 0;    // 当前是谁在提供服务private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;private String serviceId;public WeightLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;this.serviceId = serviceId;}@Overridepublic Mono<Response<ServiceInstance>> choose(Request request) {ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();return supplier.get().next().map(this::getInstanceResponse);}//每个服务访问3次,然后换下一个服务private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {log.info("进入自定义负载均衡");if (instances.isEmpty()) {return new EmptyResponse();}log.info("每个服务访问3次后轮询");int size = instances.size();ServiceInstance serviceInstance = null;while (serviceInstance == null) {System.out.println("===");if (total < 3) {serviceInstance = instances.get(index);total++;} else {total = 0;index++;if (index >= size) {index = 0;}serviceInstance = instances.get(index);}}return new DefaultResponse(serviceInstance);}}

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

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

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

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

使用配置类方式

package com.itmuch.contentcenter.rule;import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;@Configuration
public class CustomLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> loadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);//nacos的负载均衡策略,按权重分配return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,ServiceInstanceListSupplier.class),name, nacosDiscoveryProperties);}
}

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

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

配置文件方式

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

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

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

http://www.lryc.cn/news/159227.html

相关文章:

  • 【Git-Exception】Git报错:fatal: unable to auto-detect email address
  • JVM性能优化 —— 类加载器,手动实现类的热加载
  • SSH连接MobaXterm
  • 本地虚机Jumpserver使用域名访问报错 使用IP+端口没有错误
  • 备战计算机二级公共基础知识(五)----数据库设计基础
  • 【excel密码】excel文件加密方法总结:
  • MySQL之用户管理
  • 伪静态web.config常见规则写法与参数介绍说明
  • 使用kubasz快速搭建Kubernetes集群
  • php常用加密算法大全aes、3des、rsa等
  • ubuntu22.04搭建verilator仿真环境
  • python中如何使用正则表达匹配\本身?(文末赠书)
  • Linux学习之MySQL连接查询
  • 【Hello Algorithm】二叉树相关算法
  • ExpressLRS开源代码之工程结构
  • fastjson 1.2.24 反序列化导致任意命令执行漏洞复现
  • 探秘MySQL三个神秘隐藏列(mysql三个隐藏列) rownum、rowid、oid
  • leetcode刷题--数组类
  • Vue3---uni-app--高德地图引用BUG
  • Stable Diffuse 之 本地环境部署/安装包下载搭建过程简单记录
  • 护航数字政府建设,美创科技成为“数字政府建设赋能计划”成员单位
  • Kafka3.0.0版本——消费者(消费者组原理)
  • 天津web前端培训班 前端是否适合零基础学?
  • Paimon+StarRocks 湖仓一体数据分析方案
  • 界面控件DevExtreme(v23.2)下半年发展路线图
  • docker镜像配置mysql、redis
  • CentOS7无法连接网络 右上角网络图标消失
  • 为什么创建 Redis 集群时会自动错开主从节点?
  • 分布式 - 服务器Nginx:基础系列之Nginx静态资源配置优化sendfile | tcp_nopush | tcp_nodelay
  • 【动手学深度学习】--语言模型