目录
一、负载均衡概述
1.1 什么是负载均衡
负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。
1.2.自定义实现负载均衡
1.2.1.创建服务提供者
代码如下:
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.184.131 #nacos服务地址
application:
name: ribbon-provider #向注册中心注册的名字
server:
port: 9091
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.184.131 #nacos服务地址
application:
name: ribbon-provider #向注册中心注册的名字
1.2.2 创建服务消费者
controller
import com.bjpowernode.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
//访问Rest服务端
@Autowired
private RestTemplate restTemplate;
//发现服务
@Autowired
private DiscoveryClient discoveryClient;
private int currentIndex;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取nacos中注册的所有服务信息
List<String> services = discoveryClient.getServices();
//随机获取服务
int currentIndex = new Random().nextInt(2);
//轮询方式
//currentIndex = (currentIndex + 1) % services.size();
//获取nacos中注册的指定服务信息
ServiceInstance serviceInstance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
String url = "http://"+ serviceInstance.getHost()+":"+ serviceInstance.getPort()+"/provider/getUserById/"+id;
//String url = "http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
测试 随机获取服务和轮询获取服务
二、Ribbon介绍
2.1 什么是Ribbon
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
我们不需要去引入ribbon的依赖,因为在nacos里面已经集成了ribbon的依赖:
2.2 负载均衡策略
负载均衡接口:com.netflix.loadbalancer.IRule
2.2.1.随机策略
com.netflix.loadbalancer.RandomRule
:该策略实现了从服务清单中随机选择一个服务实例的功能。
2.2.2.轮询策略
com.netflix.loadbalancer.RoundRobinRule
:该策略实现按照线性轮询的方式依次选择实例的功能。具体实现如下,在循环中增加了一个count计数变量,该变量会在每次轮询之后累加并求余服务总数
2.3 基于ribbon实现负载均衡
2.3.1.修改ribbon_consumer
修改 ConfigBean:
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
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;
@Configuration
public class ConfigBean {
@Bean
/**
* 添加LoadBalanced注解,Ribbon会给restTemplate请求添加一个拦截器,
* 在拦截器中获取注册中心的服务列表,并且通过Ribbon内置的负载均衡算法获取一个服务
* 通过获取到的服务信息(ip,port) 替换为serviceId(服务名)实现负载均衡
*/
@LoadBalanced //开启负载均衡 默认是轮询方式
public RestTemplate restTemplate(){
return new RestTemplate();
}
//告诉Ribbon用负载均衡随机算法
@Bean
public IRule iRule(){
return new RandomRule();
}
}
修改 controller:
import com.bjpowernode.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
//访问Rest服务端
@Autowired
private RestTemplate restTemplate;
//发现服务
@Autowired
private DiscoveryClient discoveryClient;
private int currentIndex;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取nacos中注册的所有服务信息
List<String> services = discoveryClient.getServices();
//随机获取服务
//int currentIndex = new Random().nextInt(2);
//轮询方式
currentIndex = (currentIndex + 1) % services.size();
//获取nacos中注册的指定服务信息
ServiceInstance serviceInstance = discoveryClient.getInstances("ribbon-provider").get(currentIndex);
//String url = "http://"+ serviceInstance.getHost()+":"+ serviceInstance.getPort()+"/provider/getUserById/"+id;
String url = "http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
最后自主测试一下随机方式和轮询方式