服务之间的调用(OpenFeign)-原来如此简单


   温馨提示: 本文总共7337字,阅读完大概需要8-10分钟,希望您能耐心看完,倘若你对该知识点已经比较熟悉,你可以直接通过目录跳转到你感兴趣的地方,希望阅读本文能够对您有所帮助,如果阅读过程中有什么好的建议、看法,欢迎在文章下方留言或者私信我,您的意见对我非常宝贵,再次感谢你阅读本文。

一: 初见
一:初见

  定义: OpenFeign是一个声明式的Web服务客户端、让编写Web服务客户端变得更加容易只需要创建一个接口然后添加上注解即可,同时,它集成了Ribbon,可以轻松实现负载均衡的效果。

二: 疑惑
二:疑惑

  疑问一:为什么有了Ribbon和RestTemplate还要使用OpenFeign?
  1、首先、Feign的目的是为了更简单的编写Http客户端,在平常的开发中,一个服务可能被多处进行调用,所以可以将被调用的微服务封装成一些客户端来包装这些依赖的服务调用。
  2、Feign在此基础上做了封装,通过接口+注解完成对服务提供方的绑定,简化了调用服务的开发量。同时、Feign集成了Ribbon,可以更加简单的实现服务的调用。

  疑问二:Feign和OpenFeign有什么区别
  注:官方已经宣布停止更新Feign组件了,所以我们可以使用OpenFeign进行代替,此处列举的区别只是做一下普及Feign和OpenFeign有什么区别

Feign本身不支持Spring MVC的注解,它有一套自己的注解,调用方式如下:Feign的使用

三: 使用OpenFeign
三:使用OpenFeign

(一) 使用方式: 接口+注解 --> 完成对服务提供方的服务绑定,即可实现调用服务提供方的服务就像调用自己服务的API一样

(二) 服务提供方(服务名为:CLOUD-PAYMENT-SERVICE):
注册中心

package com.elvis.springcloud.controller;

import com.elvis.springcloud.model.CommonResult;
import com.elvis.springcloud.model.Payment;
import com.elvis.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

@RestController
@Slf4j
public class PaymentController {
    @Autowired
    private PaymentService paymentService;
    @Value("${server.port}")
    private String port;
	// 用于测试返回当前服务提供者的端口号
    @RequestMapping("/payment/test/ribbon")
    public String testCustomer(){
        return port;
    }
	// 用于模拟openFeign请求超时的API
    @RequestMapping("/payment/test/ribbon/timeout")
    public String testCustomerTimeout(){
        try{
            Thread.sleep(3000);
        }catch (Exception e){
            log.info(e.getLocalizedMessage());
        }
        return port;
    }
}

(三) 服务消费方

  1、openFeign接口,用于绑定服务提供方

package com.elvis.springcloud.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
//FeignClient表示这是使用OpenFeigin调用服务的客户端,
// value属性的值是: 提供服务的消费方的服务名称,必须指定,否则无法找到对应的服务
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface OrderFeign {
    @RequestMapping("/payment/test/ribbon")
    public String testCustomer();

    @RequestMapping("/payment/test/ribbon/timeout")
    public String testCustomerTimeout();
}

  2、客户端访问消费者

package com.elvis.springcloud.controller;

import com.elvis.springcloud.feign.OrderFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class FeignOrderController {

    @Autowired
    private OrderFeign orderFeign;

    @RequestMapping("/consumer/payment/test/ribbon")
    public String testCustomer(){
        String s = orderFeign.testCustomer();
        log.info("本次提供服务的服务端端口号为:"+s);
        return s;
    }

    @RequestMapping("/payment/test/ribbon/timeout")
    public String testCustomerTimeout(){
        return orderFeign.testCustomerTimeout();
    }
}

  3、项目配置类

package com.elvis.springcloud.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {
    // Feign调用的日志输出级别
    @Bean
    Logger.Level  getLogger(){
        return Logger.Level.FULL;
    }
    // 随机调用服务的负载均衡算法
    @Bean
    IRule getIRule(){
        return new RandomRule();
    }
}

  4、项目配置文件

server:
  port: 8010
# 注册到eureka服务
eureka:
  client:
    register-with-eureka: true
    fetch-registy: true # 是否获取注册到eureka的服务信息
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

  5、项目主启动类

package com.elvis.springcloud;

import com.elvis.springcloud.config.IRuleConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
// 激活openFeign既可以通过Feign进行服务调用
@EnableFeignClients
// value值表示: 本次负载均衡算法作用到的服务名称
// configuration属性值表示: 自定义的算法类的Class对象
//(如果我们不使用RibbonClient注解,openFeign会默认使用Ribbon的轮询算法)
@RibbonClient(value = "CLOUD-PAYMENT-SERVICE",configuration = IRuleConfig.class)
public class ConsumerFeignOrder80 {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerFeignOrder80.class,args);
    }
}

  2、实现效果图
实现效果图

四: OpenFeign超时限制
四: OpenFeign超时限制

(一) 注: OpenFeign的默认请求服务的时间1秒,如果一秒内不能请求到结果则会返回请求超时的错误
OpenFeign请求超时
(二) 解决方式: 在application.yml中配置请求超时的时间限定,重启服务即可(这里推荐使用热部署插件,这样不用每次修改后都重启服务,后面会专门开一片文章进行讲解热部署插件—事半功倍哦)

ribbon:
  ReadTimeout: 5000 # 表示与服务提供放进行链接时的最大时间(毫秒)
  ConnectionTimeout: 5000 # 表示获取服务提供放资源的的最大时间(毫秒)
五: OpenFeign日志控制级别
五: OpenFeign日志控制级别

(一) 日志: 实际上是对请求的监控和输出,我们可以通过配置来设置日志的级别,从而打印出我们需要的日志,OpenFeign的日志级别设置如下:

  1、添加日志配置类

    // Feign调用的日志输出级别
    @Bean
    Logger.Level  getLogger(){
    	// 有以下的配置类型
        return Logger.Level.FULL;
    }

在这里插入图片描述
  2、在配置文件中设置监听指定路径下的文件日志

logging:
  level:
    com.elvis.springcloud.feign.OrderFeign: debug #日志监听的位置

  3、实现效果
日志级别输出

六: 小结
六:小结

  通过上面的案例,发现OpenFeign的优点很多,且使用更加方便,本质就是通过: 接口 + 注解实现对服务提供者的绑定,从而轻松实现服务之间的调用,纸上得来终觉浅,绝知此事要躬行,希望你不单单只是看完文章,而是亲自进行动手,很多东西只有自己动手了才会发现其实没有想象中那么难。
  如果本文能够对你有一点点帮助,我会非常开心,方便的话可以帮我点击一下赞和关注,后面我会更新更多关于SpringCloud和Java相关知识的文字,如果你有什么建议,欢迎在文章下方留言或者私信我,你的建议对我非常重要,再次感谢你的阅读!

发布了49 篇原创文章 · 获赞 67 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40891009/article/details/105175251