微服务架构➖SpringCloud➖Ribbon
关于作者
- 作者介绍
🍓 博客主页:作者主页
🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉 🏆、阿里云专家博主 、51CTO专家博主
🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨💻
1. 简介
Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求 自动转换成客户端负载均衡的服务调用。 轮询 hash 权重 ... 简单的说 Ribbon 就是 netfix 公司的一个开源项目,主要功能是提供客户端负载均衡算法和 服务调用。Ribbon 客户端组件提供了一套完善的配置项,比如连接超时,重试等。 在 Spring Cloud 构建的微服务系统中, Ribbon 作为服务消费者的负载均衡器,有两种使 用方式,一种是和 RestTemplate 相结合,另一种是和 OpenFeign 相结合。OpenFeign 已经 默认集成了 Ribbon,关于 OpenFeign 的内容将会在下一章进行详细讲解。Ribbon 有很多子 模块,但很多模块没有用于生产环境!
官方网站:docs.spring.io/spring-fram...
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 创建 consumer
导入依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
3.5 编写 consumer 的启动类
java
package com.zmz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
// @LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
3.6 编写 consumer 的 TestController
java
package com.zmz.controller;
import com.netflix.loadbalancer.ILoadBalancer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.util.ObjectUtils;
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;
/**
* @ProjectName: springcloud
* @Package: com.zmz.controller
* @ClassName: TestController
* @Author: 张晟睿
* @Date: 2022/9/30 17:58
* @Version: 1.0
*/
@RestController
public class TestController {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
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 = loadBalancer(instances);
String host = serviceInstance.getHost();
int port = serviceInstance.getPort();
String url = "http://" + host + ":" + port + "/info";
System.out.println("本次调用的方法是" + url);
//拼接 url 去调用 ip:port 先自己实现不用 ribbon
String forObject = restTemplate.getForObject(url, String.class);
System.out.println(forObject);
return forObject;
}
private ServiceInstance loadBalancer(List<ServiceInstance> instances) {
ServiceInstance serviceInstance = instances.get(random.nextInt(instances.size()));
return serviceInstance;
}
}
3.7 测试
然后访问调用
3.8 使用 Ribbon 改造
只需要对 consumer 改造即可,改造启动类 改造 controlle
JAVA
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced //ribbon 的负载均衡注解
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
改造 TestControlle
JAVA
@RequestMapping("/testRibbonBalance")
public String testRibbonBalance(ServiceId serviceId) {
String url = "http://" + serviceId + "/info";
String forObject = restTemplate.getForObject(url, String.class);
System.out.println(forObject);
return forObject;
}
3.9 改造后测试
改造后测试地址:localhost:8082/testRibbonBalance?serviceId=provider
4.源码分析
事后补充!!!