B站尚硅谷最新版SpringCloud 学习笔记(5)-Ribbon负载均衡和OpenFeign服务接口调用
上一篇:B站尚硅谷最新版SpringCloud 学习笔记(4)-Consul服务注册与发现
B站视频地址:https://www.bilibili.com/video/BV18E411x7eT
文章目录
- B站尚硅谷最新版SpringCloud 学习笔记(5)-Ribbon负载均衡和OpenFeign服务接口调用
- 上一篇:[B站尚硅谷最新版SpringCloud 学习笔记(4)-Consul服务注册与发现](https://blog.csdn.net/weixin_42417934/article/details/112721644)
- 一、Ribbon概述
- 二、Ribbon负载均衡演示
- 三、RestTemplate的使用
- 四、Ribbon核心组件IRule
- 五、OpenFeign服务接口调用
- 六、OpenFeign日志打印功能
- 下一篇:[B站尚硅谷最新版SpringCloud 学习笔记(6)-Hystrix断路器](https://blog.csdn.net/weixin_42417934/article/details/112788296)
一、Ribbon概述
1.是什么
官网https://github.com/Netflix/ribbon/wiki/Getting-Started
2.作用
①LB(负载均衡)
②Nginx服务端负载均衡
③Ribbon负载均衡
二、Ribbon负载均衡演示
1.架构说明
总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。
2.POM
POM中没有引入过Ribbon,也能实现负载均衡
因为Eureka依赖整合Ribbon
三、RestTemplate的使用
1.RestTemplate
官网:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html
2.getForObject方法/getForEntity方法
3.postForObject/postForEntity
4.修改cloud-consumer-order80的方法
@GetMapping("/payment/createEntity")
public CommonResult<Payment> create2(Payment payment) {
ResponseEntity<CommonResult> resultResponseEntity = restTemplate.postForEntity(PAYMENT_URL + "/payment/create/", payment, CommonResult.class);
if (resultResponseEntity.getStatusCode().is2xxSuccessful()) {
return resultResponseEntity.getBody();
} else {
return new CommonResult<>(444, "添加失败");
}
}
@GetMapping("/payment/getEntity/{id}")
public CommonResult<Payment> getPayment2(@PathVariable("id") Long id) {
ResponseEntity<CommonResult> resultResponseEntity = restTemplate.getForEntity(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
if (resultResponseEntity.getStatusCode().is2xxSuccessful()) {
return resultResponseEntity.getBody();
} else {
return new CommonResult<>(444, "添加失败");
}
}
结果:
四、Ribbon核心组件IRule
1.IRule:根据特定算法从服务列表中选取一个要访问的服务
com.netflix.loadbalancer.RoundRobinRule | 轮询 |
---|---|
com.netflix.loadbalancer.RandomRule | 随机 |
com.netflix.loadbalancer.RetryRule | 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试 |
WeightedResponseTimeRule | 对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择 |
BestAvailableRule | 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 |
AvailabilityFilteringRule | 先过滤掉故障实例,再选择并发较小的实例 |
ZoneAvoidanceRule | 默认规则,复合判断server所在区域的性能和server的可用性选择服务器 |
2.Ribbon替换规则
对cloud-consumer-order80进行修改
①注意配置细节
官网的意思是规则类不能放在有@ComponentScan的包及子包下。
打开启动类,Ctrl+左击进去
发现包内有@ComponentScan,所以规则类不能放在启动类的所在包及子包下
②新建包,并添加规则类
规则类位置
@Configuration
public class MySelfRule {
@Bean
public IRule myRule(){
return new RandomRule();
// return new RetryRule();
// return new BestAvailableRule();
}
}
③主启动类添加@RibbonClient
注意实例名一定要大写,否则不起作用
@SpringBootApplication
@EnableEurekaClient
//注意实例名一定要大写,否则不起作用
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
//@RibbonClient(name = "cloud-payment-service",configuration = MySelfRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
④结果:
负载均衡默认的轮询算法已经换成随机算法了
3.Ribbon负载均衡算法(难点)
①原理
②源码
4.手写轮询算法
①首先在cloud-consumer-order80注释负债均衡和Ribbon
②在cloud-provider-payment8001和8002上创建接口
@GetMapping(value = "/lb")
public String getPaymentLB(){
return serverPort;
}
③在cloud-consumer-order80创建LoadBalancer接口和实现类
public interface LoadBalancer {
//收集服务器总共有多少台能够提供服务的机器,并放到list里面
ServiceInstance instances(List<ServiceInstance> serviceInstances);
}
实现类
@Component
public class MyLb implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
//获取索引
private final int getAndIncrement() {
int next;
int current;
do {
current = this.atomicInteger.get();
next = current >= Integer.MAX_VALUE ? 0 : current + 1;
} while (!this.atomicInteger.compareAndSet(current,next));
System.out.println("****第几次访问,next:"+ next);
return next;
}
}
④修改cloud-consumer-order80控制层
⑤测试,实现轮询算法
代码:https://gitee.com/yezhinao/SpringCloud-Learn/tree/master/mycloud2020(5.1)
五、OpenFeign服务接口调用
1.概述
①是什么
Feign是一个声明式的web服务客户端,让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可
②作用
③Feign和OpenFeign两者区别
2.OpenFeign使用步骤
Feign在消费端使用
①创建cloud-consumer-feign-order80
②修改POM,添加application.yml,添加启动类
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mycloud2020</artifactId>
<groupId>org.yezhinao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-feign-order80</artifactId>
<!--openfeign-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.yezhinao</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
启动类
@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain80.class, args);
}
}
③新建PaymentFeignService接口并新增注解@FeignClient
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id);
}
④控制层Controller
@RestController
@RequestMapping(value = "consumer")
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
return paymentFeignService.getPaymentById(id);
}
}
⑤测试
先启动2个eureka集群7001/7002,再启动2个微服务8001/8002,启动OpenFeign启动
http://localhost/consumer/payment/get/1
而且自带负载均衡
openFegin包下自带Ribbon,所以自动实现负载均衡
3.OpenFeign超时控制
①服务提供方8001故意写暂停程序
@GetMapping(value = "/feign/timeout")
public String paymentFeignTimeout(){
try { TimeUnit.SECONDS.sleep(3); }catch (Exception e) {e.printStackTrace();}
return serverPort;
}
②服务消费方80添加超时方法PaymentFeignService
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout();
③服务消费方80添加超时方法OrderFeignController
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout(){
return paymentFeignService.paymentFeignTimeout();
}
④测试
首先测提供者8001的方法
http://localhost:8001/payment/feign/timeout
等待三秒后访问成功
http://localhost/consumer/payment/feign/timeout
访问错误
原因超时
⑤避免超时
#设置feign客户端超时时间(openFeign默认支持ribbon)
ribbon:
#发的足建立连拔后从服务器读取到可用资源所用的时间
ReadTimeout: 5000
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接房用的时间
ConnectTimeout: 5000
重新访问
http://localhost/consumer/payment/feign/timeout
六、OpenFeign日志打印功能
1.日志打印功能
2.日志级别
3.配置
配置日志bean
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
YML文件里需要开启日志的Feign客户端
logging:
level:
# feign 日志以什么级别监控哪个接口
com.yezhinao.springcloud.service.PaymentFeignService: debugy
结果http://localhost/consumer/payment/feign/timeout
代码:https://gitee.com/yezhinao/SpringCloud-Learn/tree/master/mycloud2020(5.2)