MENU

OpenFeign服务调用

• May 20, 2020 • Read: 38 • 技术笔记,SpringCloud

Feign

Feign 是一个声明式 WebService 客户端。使用 Feign 能让编写Web Service 客户端更加简单。

Feign 旨在使编写Java Http 客户端变得更容易。
前面在使用 Ribbon+RestTemplate时,利用RestTemplate 对http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign 在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注衣一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。

Feign集成了Ribbon

利用Ribbon维护了Payment 的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign 只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

OpenFeign

OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

开启Feign主启动类上加@EnableFeignClients注解

几个简单的示例代码:

我先在消费端80启动类中添加注解

@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class,args);
    }
}
@FeignClient(value = "cloud-payment-service")
public interface PaymentFeignService {

    //直接用URI的方式去8001/8002集群去调用服务

    @GetMapping("/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

    @GetMapping("/payment/feign/timtout")
    String paymentFeignTimeout();
}
@RestController
public class OrderFeignController {

    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping(value = "/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        return paymentFeignService.getPaymentById(id);
    }
}

OpenFeign超时控制

默认Feign客户端只等待一秒钟, 但是服务端处理需要超过1秒钟,导致Feign客户端不想等待了,直接返回报错。为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制。

怎么做呢,直接在application.yml中配置即可。

重点:由于Feign天生支持Ribbon所以在超时控制这块由Ribbon来控制

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

不放心的朋友可以用线程等待来测试一下:

在服务提供者中添加一个故意等待的方法:

@GetMapping("/payment/feign/timtout")
public String paymentFeignTimeout(){
    try{
        TimeUnit.SECONDS.sleep(3);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return serverPort;
}

在消费者这边去调用一下:

@GetMapping("/payment/feign/timtout")
String paymentFeignTimeout();
@GetMapping("/consumer/payment/feign/timtout")
String paymentFeignTimeout() {
    return paymentFeignService.paymentFeignTimeout();
}

访问,你会发现不加超时控制配置,就会超时的错误。加上即可!

日志打印

Feign 提供了日志打印功能,可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节。
说白了就是对接口的调用情况进行监控和输出

日志级别

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

怎么开启呢,添加一个配置类:

@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignloggerLevel(){
        return Logger.Level.FULL;
    }
}

application.yml

logging:
  level:
    #feign日志以什么级别监控哪个接口,注意,这里是你要监控的接口类全路径
    com.xn2001.springcloud.service.PaymentFeignService: debug
本站所有未注明转载的文章均为原创,并采用CC BY-NV-SA 4.0 授权协议,转载请注明来源。

Archives QR Code
QR Code for this page
Tipping QR Code