目录
一、模块一:提供数据
1.1 首先将第一个实例打包
1.2 使用命令行设置不同权重
1.3 打开图形化界面看看权重是否配置成功。
二、模块二:调用模块一
三、修改默认负载均衡策略
四、自定义规则
编辑 五、完整代码
5.1 目录结构
5.2 配置文件
5.3 RestTemplateConfig.java
5.4 MyRule.java
5.5 RibbonConfig.java
5.6 GetStudentController.java
六、完整代码
一、模块一:提供数据
1.1 首先将第一个实例打包
1.2 使用命令行设置不同权重
先设置权重,再设置-jar,另外模块一的配置文件不要填权重配置,配了再用命令行不生效。
java -Dspring.cloud.nacos.discovery.weight=5 -jar --server.port=8081
Unrecognized option: --server.port=8081
同理 再开一个设置权重为2
java -Dspring.cloud.nacos.discovery.weight=2 -jar nacos-nacos-discovery1-0.0.1-SNAPSHOT.jar --server.port=8082
1.3 打开图形化界面看看权重是否配置成功。
二、模块二:调用模块一
其中为了方便,我用的上次代码 age代表权重。
再次点击
可以看出默认采用轮播的形式
三、修改默认负载均衡策略
/**
* 修改默认负载均衡策略
*/
@Configuration
public class RibbonConfig {
@Bean
public IRule rule(){
/** 生成随机策略**/
return new RandomRule();
}
}
再次访问模块一后 随机访问
采用nacos策略,会根据权重占比,来负载均衡
四、自定义规则
1.1 MyRule.java
package com.beiyou.config;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
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.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class MyRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
//JUC包下,线程安装的Integer
private static AtomicInteger count = new AtomicInteger(0);
private Server server = null;
@Override
@SneakyThrows
public Server choose(Object key) {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
//获取服务名称
String serverName = loadBalancer.getName();
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
List<Instance> allInstances = namingService.getAllInstances(serverName, true);
//6062
Instance maxInstance = allInstances.stream().max(Comparator.comparing(Instance::getWeight)).get();
//6061
Instance minInstance = allInstances.stream().min(Comparator.comparing(Instance::getWeight)).get();
int count2 = count.addAndGet(1);
System.out.println(count2);
int mod = count2 % 5; //取模运算 5,10,15,20,25 ...
if(mod == 0){ //当次数是5的倍数的时候,mod就是0,
server = new Server(minInstance.getIp(),minInstance.getPort());
} else {
//mod 是 1,2,3,4 的时候打到权重高的这个机器上
server = new Server(maxInstance.getIp(),maxInstance.getPort());
}
return server;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
返回自定义的规则
我们自定义的规则是含能除尽5就负载到权重为2的机器,否则负载到权重为5的机器。
① 使用自己的规则(两种配置方式)
使用注解配置
@Configuration
@RibbonClients(defaultConfiguration = MyRule.class) //全局设置负载规则,默认是轮询的
@RibbonClient(name = "nacos-a", configuration = MyRule.class) //针对某个服务,特殊配置
public class RibbonConfig {
/**
* 全局配置
* 指定负载均衡策略
*/
@Bean
public IRule iRule() { //使用自己的规则 return new MyRule();
}}
Java
基于配置文件配置,调用指定微服务提供的服务时,使用对应的负载均衡算法
#配置具体某一个服务个性化规则
nacos-b.ribbon.NFLoadBalancerRuleClassName=com.beiyou.config.MyRule
##配置全局的负载均衡规则 (不生效)
default.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
Erlang
如果同时应用了以上两种方式去配置负载均衡,注解的优先级更高,则以注解为准.
因为配置文件的加载顺序在注解之前,后加载的配置会覆盖先前配置。
推荐使用配置文件,可以放进nacos,比较灵活。
五、完整代码
5.1 目录结构
5.2 配置文件
spring.application.name = d3
server.port = 8085
spring.cloud.nacos.discovery.server-addr = 192.168.11.82:8848
logging.level.root = error
logging.level.com.beiyou = debug
5.3 RestTemplateConfig.java
package com.beiyou.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 使用RestTemplate进行服务调用
*/
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
5.4 MyRule.java
package com.beiyou.config;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
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.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class MyRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
//JUC包下,线程安装的Integer
private static AtomicInteger count = new AtomicInteger(0);
private Server server = null;
@Override
@SneakyThrows
public Server choose(Object key) {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
//获取服务名称
String serverName = loadBalancer.getName();
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
List<Instance> allInstances = namingService.getAllInstances(serverName, true);
//6062
Instance maxInstance = allInstances.stream().max(Comparator.comparing(Instance::getWeight)).get();
//6061
Instance minInstance = allInstances.stream().min(Comparator.comparing(Instance::getWeight)).get();
int count2 = count.addAndGet(1);
System.out.println(count2);
int mod = count2 % 5; //取模运算 5,10,15,20,25 ...
if(mod == 0){ //当次数是5的倍数的时候,mod就是0,
server = new Server(minInstance.getIp(),minInstance.getPort());
} else {
//mod 是 1,2,3,4 的时候打到权重高的这个机器上
server = new Server(maxInstance.getIp(),maxInstance.getPort());
}
return server;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
5.5 RibbonConfig.java
package com.beiyou.config;
import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 修改默认负载均衡策略
*/
@Configuration
public class RibbonConfig {
@Bean
public IRule rule(){
/** 生成随机策略**/
return new MyRule();
}
}
5.6 GetStudentController.java
package com.beiyou.controller;
import com.beiyou.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RefreshScope
public class GetStudentController {
/**
* 用B应用调用A应用
*/
@Autowired
RestTemplate restTemplate;
@GetMapping("/api/b")
public List<Student> getAllStudents() {
List listStudents = restTemplate.getForObject("http://d1/api/d1", List.class);
return listStudents;
}
}
六、完整代码
云效完整代码
https://codeup.aliyun.com/62858d45487c500c27f5aab5/spring-cloud-alibaba-root.git