B站尚硅谷最新版SpringCloud 学习笔记(5)-Ribbon负载均衡和OpenFeign服务接口调用

B站尚硅谷最新版SpringCloud 学习笔记(5)-Ribbon负载均衡和OpenFeign服务接口调用

上一篇:B站尚硅谷最新版SpringCloud 学习笔记(4)-Consul服务注册与发现

B站视频地址:https://www.bilibili.com/video/BV18E411x7eT

一、Ribbon概述

1.是什么

官网https://github.com/Netflix/ribbon/wiki/Getting-Started

image-20210116215807618

2.作用

①LB(负载均衡)

image-20210116220018442

②Nginx服务端负载均衡

image-20210116220049451

③Ribbon负载均衡

image-20210116220111779

二、Ribbon负载均衡演示

1.架构说明

image-20210116220747201

image-20210116220756847

总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

2.POM

POM中没有引入过Ribbon,也能实现负载均衡

image-20210116220942390

因为Eureka依赖整合Ribbon

image-20210116221114733

三、RestTemplate的使用

1.RestTemplate

官网:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

image-20210116221337169

2.getForObject方法/getForEntity方法

image-20210116221508641

3.postForObject/postForEntity

image-20210116221543620

image-20210116221636283

4.修改cloud-consumer-order80的方法

image-20210116222731323

@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, "添加失败");
    }
}

结果:

image-20210116222851879

image-20210116222857770

四、Ribbon核心组件IRule

1.IRule:根据特定算法从服务列表中选取一个要访问的服务

image-20210117095003551

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进行修改

①注意配置细节

image-20210117095710802

image-20210117095721756

官网的意思是规则类不能放在有@ComponentScan的包及子包下。

打开启动类,Ctrl+左击进去

image-20210117095856487

发现包内有@ComponentScan,所以规则类不能放在启动类的所在包及子包下

image-20210117095939643

②新建包,并添加规则类

规则类位置

image-20210117100227098

image-20210117100436494

@Configuration
public class MySelfRule {

    @Bean
    public IRule myRule(){
        return new RandomRule();
//        return new RetryRule();
//        return new BestAvailableRule();
    }


}

③主启动类添加@RibbonClient

注意实例名一定要大写,否则不起作用

image-20210117102500372

@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);
    }
}

④结果:

负载均衡默认的轮询算法已经换成随机算法了

image-20210117102033547

image-20210117102036679

image-20210117102040190

3.Ribbon负载均衡算法(难点)

①原理

image-20210117121709546

②源码

image-20210117122215659

image-20210117123336428

4.手写轮询算法

①首先在cloud-consumer-order80注释负债均衡和Ribbon

image-20210117182206819

image-20210117182201426

②在cloud-provider-payment8001和8002上创建接口

image-20210117182302369

@GetMapping(value = "/lb")
public String getPaymentLB(){
    return serverPort;
}

③在cloud-consumer-order80创建LoadBalancer接口和实现类

image-20210117182522047

public interface LoadBalancer {

    //收集服务器总共有多少台能够提供服务的机器,并放到list里面
    ServiceInstance instances(List<ServiceInstance> serviceInstances);
}

实现类

image-20210117182749611

@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控制层

image-20210117182849447

⑤测试,实现轮询算法

image-20210117183012293

image-20210117183024147

image-20210117183005772

代码:https://gitee.com/yezhinao/SpringCloud-Learn/tree/master/mycloud2020(5.1)

五、OpenFeign服务接口调用

1.概述

①是什么

Feign是一个声明式的web服务客户端,让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可

image-20210117223608513

image-20210117223620101

②作用

image-20210117223652390

③Feign和OpenFeign两者区别

image-20210117223705157

2.OpenFeign使用步骤

Feign在消费端使用

image-20210117224024465

①创建cloud-consumer-feign-order80

image-20210117224507348

②修改POM,添加application.yml,添加启动类

POM

image-20210117224652878

<?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

image-20210117235122796

server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka

启动类

image-20210117235140347

@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class, args);
    }
}

③新建PaymentFeignService接口并新增注解@FeignClient

image-20210118000824239

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id);
}

④控制层Controller

image-20210118000921509

@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

而且自带负载均衡

image-20210118001003426

image-20210118001352397

openFegin包下自带Ribbon,所以自动实现负载均衡

image-20210118002307411

3.OpenFeign超时控制

①服务提供方8001故意写暂停程序

image-20210118001627376

@GetMapping(value = "/feign/timeout")
    public String paymentFeignTimeout(){
        try { TimeUnit.SECONDS.sleep(3); }catch (Exception e) {e.printStackTrace();}
        return serverPort;
    }

②服务消费方80添加超时方法PaymentFeignService

image-20210118001712911

@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout();

③服务消费方80添加超时方法OrderFeignController

image-20210118001813268

@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout(){
    return paymentFeignService.paymentFeignTimeout();
}

④测试

首先测提供者8001的方法

http://localhost:8001/payment/feign/timeout

等待三秒后访问成功

image-20210118002006682

http://localhost/consumer/payment/feign/timeout

访问错误

image-20210118002059592

原因超时

image-20210118002411387

⑤避免超时

image-20210118002824874

#设置feign客户端超时时间(openFeign默认支持ribbon)
ribbon:
  #发的足建立连拔后从服务器读取到可用资源所用的时间
  ReadTimeout:  5000
  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接房用的时间
  ConnectTimeout: 5000

重新访问

http://localhost/consumer/payment/feign/timeout

image-20210118002950650

六、OpenFeign日志打印功能

1.日志打印功能

image-20210118003043829

2.日志级别

image-20210118003107391

3.配置

配置日志bean

image-20210118003727193

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

YML文件里需要开启日志的Feign客户端

image-20210118003812680

logging:
  level:
    # feign 日志以什么级别监控哪个接口
    com.yezhinao.springcloud.service.PaymentFeignService: debugy

结果http://localhost/consumer/payment/feign/timeout

image-20210118003640258

代码:https://gitee.com/yezhinao/SpringCloud-Learn/tree/master/mycloud2020(5.2)

下一篇:B站尚硅谷最新版SpringCloud 学习笔记(6)-Hystrix断路器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值