OpenFeign简单介绍和基本使用


OpenFeign简单介绍和基本使用

简介

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

它的使用方法是定义一个服务接口然后在上面添加注解,Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡

Feign能干什么

Feign旨在使编写Java Http客户端变得更容易

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

Feign集成了Ribbon,通过feign只需要定义服务绑定接口并且以声明式的方法,优雅而简单的实现了服务调用

Feign和OpenFeign的区别

Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务

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

基本使用

引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency> 

编写service接口调用远程服务,添加@FeignClient注解(value:调用的服务名)

package com.yl.openfeign.order.service;

import com.yl.common.entity.CommonResult;
import com.yl.common.entity.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * 支付
 *
 * @auther Y-wee
 */
@Component
@FeignClient(value = "PAYMENT")
public interface PaymentFeignService {
    /**
     * 根据id查询数据
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/payment/get/{id}")
    CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}

编写controller

package com.yl.openfeign.order.controller;

import com.yl.common.entity.CommonResult;
import com.yl.common.entity.Payment;
import com.yl.openfeign.order.service.PaymentFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 支付
 *
 * @auther Y-wee
 */
@RequestMapping("/order")
@RestController
@Slf4j
public class OrderFeignController {
    @Resource
    private PaymentFeignService paymentFeignService;

    /**
     * 根据id查询数据
     *
     * @param id id
     * @return 查询结果
     */
    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        return paymentFeignService.getPaymentById(id);
    }
}

feign相关配置

ribbon:
  # 默认feign客户端只等待1s,但是服务端处理需要超过1s,导致feign客户端不想等待了,直接返回报错
  # 为了避免这样的情况,我们需要设置feign客户端超时时间
  # 设置建立连接后调用服务超时时间
  ReadTimeout: 5000
  # 设置连接超时时间
  ConnectTimeout: 5000

主启动类添加@EnableFeignClients

package com.yl.openfeign.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OpenFeignOrder80Application {

    public static void main(String[] args) {
        SpringApplication.run(OpenFeignOrder80Application.class,args);
    }

}

被调用的服务controller

package com.yl.payment.controller;

import com.yl.common.entity.CommonResult;
import com.yl.common.entity.Payment;
import com.yl.payment.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 支付
 *
 * @auther Y-wee
 */
@RestController
@Slf4j
@RequestMapping("/payment")
public class PaymentController {
    @Resource
    private PaymentService paymentService;
    @Value("${server.port}")
    private String serverPort;

    /**
     * 查询数据
     *
     * @param id id
     * @return 查询结果
     */
    @GetMapping(value = "/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
        Payment payment = paymentService.getPaymentById(id);
        if (payment != null) {
            return new CommonResult(200, "查询成功:" + serverPort, payment);
        }
        return new CommonResult(444, "没有对应记录,查询ID: " + id, null);
    }

}

OpenFeign日志

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

新建feign配置类

package com.yl.openfeign.order.config;

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

/**
 * feign配置类
 *
 * @auther Y-wee
 */
@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel() {
        /**
         * NONE:默认的,不显示任何日志
         * BASIC:仅记录请求方法、URL、响应状态码及执行时间
         * HEADERS:除了BASIC中定义的信息外,还有请求和响应头的信息
         * FULL:除了HEADERS中定义的信息外,还有请求和响应的正文及元数据
         */
        return Logger.Level.FULL;
    }
}

修改配置文件

logging:
  level:
    # feign日志以什么级别监控哪个接口(注意接口名和包名不要写错)
    com.yl.openfeign.order.service.PaymentFeignService: debug

通过feign调用服务,控制台显示日志,eg:


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM