欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 SpringCloud(3)--服务调用(Ribbon、OpenFeign)

程序员文章站 2022-07-02 23:02:47
文章目录服务调用RibbonRibbon的使用Ribbon常用负载均衡算法修改Order模块自定义负载均衡算法OpenFeignOpenFeign的使用OpenFeign超时机制OpenFeign日志系列链接:GitHub:源码SpringCloud(1)–入门、版本、环境搭建SpringCloud(2)–服务注册与发现(Eureka、Zookeeper、Consul)…服务调用RibbonSpring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端,...

系列链接:


服务调用

Ribbon

Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端,主要功能是提供客户端的软件负载均衡算法和服务调用。

注:Ribbon虽然大规模运用,但目前也进入维护,基本上不准备更新了

负载均衡:将用户的请求平摊的分配到多个服务上,常见的负载均衡软件有Nginx等。

Ribbon本地负载均衡客户端与Nginx服务端负载均衡的区别:

  • Nginx是服务器负载均衡,客户端所有请求交给 Nginx,然后由 Nginx 实现转发请求。

  • Ribbon是本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到 JVM 本地,从而在本地实现 RPC 远程服务调用技术。

由上面的区别可以将负载均衡分为两种:

  • 集中式LB:在服务的消费方和提供方之间使用独立的LB设施(Nginx)
  • 进程内LB:将LB的逻辑继承到消费方,消费方从服务注册中心获知哪些提供方地址可用,然后自己进行选择(Ribbon)

Ribbon就是一个软负载均衡的客户端组件,就是负载均衡+RestTemplate调用,与Eureka结合的架构如下:
荐
                                                        SpringCloud(3)--服务调用(Ribbon、OpenFeign)


Ribbon的使用

  1. 我们之前实现了负载均衡就是基于 Ribbon,其实在使用eureka的新版本时,默认就集成了Ribbon。

    		<!--eureka client-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
  2. RestTemplate类

    • xxxForObject()方法:返回的是响应体中的数据
    • xxxForEntity()方法:返回的是entity对象,包含响应体数据、响应体信息(状态码等)

Ribbon常用负载均衡算法

Riboon使用 IRule 接口,根据特定算法从所有服务中,选择一个服务。而I Rule 接口有7个实现类。每个实现类代表一个负载均衡算法:

  • com.netflix.loadbalancer.RoundRobinRule:轮询
  • com.netflix.loadbalancer.RandomRule:随机
  • com.netflix.loadbalancer.RetryRule:先轮询,失败则在指定时间内进行重试
  • WeightedResponseTimeRule:对轮询的扩展,响应速度越快权重越大
  • BestAvailableRule:先过滤处于断路状态的服务,选择一个并发量最小的服务
  • AvailabilityFilteringRule:先过滤故障实例,再选择并发较小的实例
  • ZoneAvoidanceRule默认规则,根据Server所在区域的性能和可用性选择服务器。

修改Order模块

有两点需要注意:

  • 这里使用 Eureka 的相关服务

  • IRule 自定义配置类不能放在@ComponentScan所扫描的当前包以及子包下

    (有@SpringBootApplication注解的Main所在的包)

  1. 额外创建一个包
    荐
                                                        SpringCloud(3)--服务调用(Ribbon、OpenFeign)

  2. 创建配置类,指定负载均衡算法

            @Configuration
            public class MySelfRule {
                @Bean
                public IRule myRule(){
                    return new RandomRule();//随机负载均衡算法
                }
            }
    
  3. 在主启动类上加@RibbonClient注解,表示访问CLOUD-PAYMENT-SERVICE服务时,使用我们自定义的负载均衡算法

            @SpringBootApplication
            @EnableEurekaClient
            @RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
            public class OrderMain80 {
                public static void main(String[] args){
                    SpringApplication.run(OrderMain80.class,args);
                }
            }
    

自定义负载均衡算法

ribbon的轮询算法原理

rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务器重启计数从1开始。
荐
                                                        SpringCloud(3)--服务调用(Ribbon、OpenFeign)

自定义负载均衡算法

实现轮询方式的负载均衡算法。

  1. 给pay模块(8001,8002)的controller方法添加一个方法,返回当前节点端口

            @GetMapping("/lb")
            public String getPaymentLB(){
                return serverPort;
            }
    
  2. 修改order模块,去掉ApplicationContextConfig中的 @LoadBalanced 注解,以及Main上的@RibbonClient注解

  3. 自定义接口

            public interface LoadBalancer {
                //从服务列表中选取一个服务
                ServiceInstance instances(List<ServiceInstance> serviceInstances);
            }
    
  4. 接口实现类

            @Component
            public class MyLB implements LoadBalancer {
    
                private AtomicInteger atomicInteger = new AtomicInteger(0);
    
                private final int getAndIncrement(){
                    int current;
                    int next;
                    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;
                }
    
                @Override
                public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
                    int index = getAndIncrement() % serviceInstances.size();
                    return serviceInstances.get(index);
                }
            }
    
  5. 修改controller:

            @Resource
            private LoadBalancer loadBalancer;//自定义的
            @Resource
            private DiscoveryClient discoveryClient;
    
            @GetMapping("/payment/lb")
            public String getPaymentLB(){
                List<ServiceInstance> serviceInstances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
                if(serviceInstances == null || serviceInstances.size() <= 0){
                    return null;
                }
                ServiceInstance instance = loadBalancer.instances(serviceInstances);
                URI url = instance.getUri();
                return restTemplate.getForObject(url+"/payment/lb",String.class);
            }
    
  6. 启动服务,测试接口
    荐
                                                        SpringCloud(3)--服务调用(Ribbon、OpenFeign)

OpenFeign

Feign是一个声明式WebService客户端,服务调用只需在自己的接口上添加相应的注解。其简化了使用 Spring Cloud Ribbon 时,自动封装服务调用客户端的开发过程,其实 Feign 底层集成了 Ribbon 和 RestTemplate。

Feign与OpenFeign区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNbFY4C1-1594459297952)(https://hw.mokespace.cn/images/2020/07/11/242dd143bf8a766ead4941bef46bf3b0.png)]


OpenFeign的使用

  1. 新建一个order项目,用于feign测试,名称为 cloud-consumer-feign-order80

  2. pom文件,比原始的多一个openfeign依赖

    		<!-- openfeign -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    
  3. 配置文件

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

            @SpringBootApplication
            @EnableFeignClients //开启
            public class OrderFeginMain80 {
                public static void main(String[] args){
                    SpringApplication.run(OrderFeginMain80.class,args);
                }
            }
    
  5. fegin需要调用的其他的服务的接口

    @FeignClient(value = "CLOUD-PAYMENT-SERVICE")
    public interface PaymentService {
    
        @GetMapping("/payment/get/{id}")
        public CommonResult getPaymentById(@PathVariable("id") Long id);
    }
    
  6. controller

            @RestController
            @Slf4j
            @RequestMapping("/consumer")
            public class OrderFeginController {
    
                @Resource
                private PaymentService paymentService;
    
                @GetMapping("/payment/get/{id}")
                public CommonResult<Payment> getPyamentById(@PathVariable("id")Long id){
                    return paymentService.getPaymentById(id);
                }
            }
    
  7. 测试:启动两个erueka(7001,7002)、两个pay(8001,8002)、当前的order模块


OpenFeign超时机制

首先,OpenFeign 默认等待时间是1秒,超过1秒会直接报错,如下图:
荐
                                                        SpringCloud(3)--服务调用(Ribbon、OpenFeign)

设置超时时间,修改配置文件

因为OpenFeign的底层是ribbon进行负载均衡,所以它的超时时间是由ribbon控制,所以在配置文件对 ribbon 进行配置:

        ribbon:
          # 建立连接后,在服务端读取数据的时间
          ReadTimeout: 5000
          # 建立连接所需的时间
          ConnetTimeout: 5000

OpenFeign日志

Feign提供了日志打印的功能,可以调整日志级别来了解接口的调用情况。

OpenFeign的日志级别有:

  • NOEE:默认,不显示日志
  • BASIC:仅记录请求方法、URL、响应状态码以及执行时间
  • HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息
  • FULL:除了 HEADERS 中定义的信息外,还有请求和响应的正文以及元数据

使用OpenFeign的日志:

  1. 实现在配置类中添加OpenFeign的日志类

            @Configuration
            public class FeignConfig {
                @Bean
                public Logger.Level feignLoggerLevel(){
                    return Logger.Level.FULL;//日志级别
                }
            }
    
  2. 为指定类设置日志级别,配置文件中

            logging:
              level:
                # feign 日志以什么级别监控哪个接口
                com.moke.springcloud.service.PaymentService: debug
    
  3. 启动服务即可
    荐
                                                        SpringCloud(3)--服务调用(Ribbon、OpenFeign)

本文地址:https://blog.csdn.net/MOKEXFDGH/article/details/107287927