loadbalancer用于对提供服务的集群做一个节点的选取规则。
如图所示,load balancer集成在调用方
示例
- 创建loadbalance-base模块,并引入相关依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> </dependencies>
版本信息
<properties> <spring-boot.version>2.4.2</spring-boot.version> <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version> <nacos.version>2021.1</nacos.version> <spring-cloud.version>2020.0.1</spring-cloud.version> <spring-cloud-bootstrap.version>3.0.3</spring-cloud-bootstrap.version> <spring-cloud-loadbalancer.version>3.0.1</spring-cloud-loadbalancer.version> </properties>
- 创建服务提供者模块loadbalancer-provider-service
- 主类
@EnableDiscoveryClient @SpringBootApplication public class LoadBalanceProviderApplication { public static void main(String[] args) { SpringApplication.run(LoadBalanceProviderApplication.class, args); } }
- 配置
spring: application: name: loadbalance-provider-service cloud: nacos: config: group: loadbalance-group namespace: loadbalance server-addr: 192.168.56.102:8848 file-extension: yml prefix: ${spring.application.name} discovery: group: loadbalance-group namespace: loadbalance server-addr: 192.168.56.102:8848 weight: 5 server: port: 8082
- 服务类
@RestController public class TestController { @Value("${server.port}") private int port; @GetMapping("/service") public String test(){ return "provicer servvice: [from port]:" + port; } }
- 启动nacos,创建响应的命名空间,并开启多实例服务,分别开启
8081
,和8082
的两个loadbalance-provider-service服务实例
- 创建loadbalancer-consumer-service
- 主类
@SpringBootApplication @EnableDiscoveryClient public class LoadBalanceConsumerApplication { public static void main(String[] args) { SpringApplication.run(LoadBalanceConsumerApplication.class, args); } }
- restTemplate配置类,此处必须在restTemplate上加上
@LoadBalanced
注解
@Configuration public class LoadConfiguration { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
- 服务类,restTemplate调用host:port改为服务提供者的名称
@RestController public class TestController { @Resource private RestTemplate restTemplate; @GetMapping("/service") public String test(){ return restTemplate.getForObject("http://loadbalance-provider-service/service", String.class); } }
- 配置
spring: application: name: loadbalance-consumer-service cloud: nacos: config: group: loadbalance-group namespace: loadbalance server-addr: 192.168.56.102:8848 file-extension: yml prefix: ${spring.application.name} discovery: group: loadbalance-group namespace: loadbalance server-addr: 192.168.56.102:8848 weight: 1 server: port: 9091
- 启动loadbalacer-consumer-service服务
访问localhost:9091/service,并多次刷新,可以看到8081,和8082两个服务交替
provicer servvice: [from port]:8081 provicer servvice: [from port]:8082 provicer servvice: [from port]:8081 provicer servvice: [from port]:8082 provicer servvice: [from port]:8081 provicer servvice: [from port]:8082 ....
Load Balancer提供的策略
RoundRobin: 轮询策略,意思循环往复的的服务进行选取。
Random: 随机策略,随机对服务选取一个节点
Load Balancer的默认负载策略
RoundRobin: 轮询策略,意思循环往复的的服务进行选取。
替换默认的负载策略,使用随机策略模式
新建RandomLoadBalanceConfiguration配置类,将随机策略配置进去
public class RandomLoadBalanceConfiguration { @Bean public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new RandomLoadBalancer(loadBalancerClientFactory .getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
按照官方说法配置类The classes you pass as @LoadBalancerClient or @LoadBalancerClients configuration arguments should either not be annotated with @Configuration or be outside component scan scope.
配置类不能加@Configuation注解或者要放在不被Spring容器扫描到的地方,意思要放在和主类平级的包下,不能放在主类的包或者子包。
在主类或者某个能被扫描到的配置类上加上@LoadBalancerClients
1.配置全局策略
@LoadBalancerClients(defaultConfiguration = WeightLoadBalanceConfiguration.class)
- 针对服务配置策略
@LoadBalancerClients({ @LoadBalancerClient(name = "loadbalance-provider-service", configuration = RandomLoadBalanceConfiguration.class) })