1.Ribbon 概述
Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。 轮询 hash 权重 …
简单的说 Ribbon 就是 netfix 公司的一个开源项目,主要功能是提供客户端负载均衡算法和服务调用。Ribbon 客户端组件提供了一套完善的配置项,比如连接超时,重试等。
在 Spring Cloud 构建的微服务系统中, Ribbon 作为服务消费者的负载均衡器,有两种使用方式,一种是和 RestTemplate 相结合,另一种是和 OpenFeign 相结合。OpenFeign 已经默认集成了 Ribbon,关于 OpenFeign 的内容将会在下一章进行详细讲解。Ribbon 有很多子模块,但很多模块没有用于生产环境!
/**
* 测试发送 get 请求
*/
@Test
void testGet() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/testGet?name=cxs";
ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
System.out.println(result.getStatusCodeValue());
}
/**
* 测试发送 post 表单参数
*/
@Test
void testPost() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/testPost";
LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("name", "cxs");
map.add("age", "18");
ResponseEntity<String> result = restTemplate.postForEntity(url, map, String.class);
System.out.println(result.getStatusCodeValue());
}
/**
* 测试发送 post JSON 参数
*/
@Test
void testPost2() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/testPost2";
User user = new User();
user.setName("cxs");
user.setAge(18);
user.setHobby("编码");
ResponseEntity<String> result = restTemplate.postForEntity(url, user, String.class);
System.out.println(result.getStatusCodeValue());
}
2.负载均衡
负载均衡,英文名称为 Load Balance(LB)http:// lb://(负载均衡协议) ,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如 Web 服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
2.1 服务器的负载均衡
Nginx,F5
3.Ribbon 快速入门
3.1 本次调用设计图
3.2 项目搭建
consumer 和 provider-1 和 provider-2 都是 eureka-client
注意这三个依赖是 eureka-client
注意 provider-1 和 provider-2 的 spring.application.name=provider
注意启动类的注解和配置文件的端口以及服务名称
3.3 创建 provider-1 和 provider-2
3.4 编写 provider-1 和 provider-2
3.5 创建 consumer
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.9.RELEASE</version>
</dependency
3.6 编写 consumer
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
static Random random = new Random();
@RequestMapping("/testBalance")
public String testBalance(String serviceId) {
//获取服务列表
List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
if (ObjectUtils.isEmpty(instances)) {
return "服务列表为空";
}
//如果服务列表不为空,先自己做一个负载均衡
ServiceInstance serviceInstance = loadBalance(instances);
String host = serviceInstance.getHost();
int port = serviceInstance.getPort();
String url = "http://" + host + ":" + port + "/info";
System.out.println("本次我调用的是" + url);
String forObject = restTemplate.getForObject(url, String.class);
System.out.println(forObject);
return forObject;
}
private ServiceInstance loadBalance(List<ServiceInstance> instances) {
//拼接 url 去调用 ip:port 先自己实现不用 ribbon
ServiceInstance serviceInstance =
instances.get(random.nextInt(instances.size()));
return serviceInstance;
}
}
3.9 使用 Ribbon 改造
只需要对 consumer 改造即可,改造启动类
改造 controller
**
* 用来发请求的
*
* @return
*/
@Bean
@LoadBalanced //ribbon 的负载均衡注解
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**
* 测试 ribbon 的负载均衡
*
* @param serviceId
* @return
*/
@RequestMapping("/testRibbonBalance")
public String testRibbonBalance(String serviceId) {
//直接用服务名称替换 ip:port
String url = "http://" + serviceId + "/info";
String forObject = restTemplate.getForObject(url,String.class);
System.out.println(forObject);
return forObject;
}