Spirng Cloud OpenFeign

683 阅读4分钟

Spirng Cloud OpenFeign

  Feign是一个声明式的HTTP客户端组件,它旨在是编写Http客户端变得更加容易。OpenFeign添加了对于Spring MVC注解的支持,同时集成了Spring Cloud LoadBalancerSpring Cloud CircuitBreaker,在使用Feign时,提供负载均衡和熔断降级的功能。

1. 入门案例

1.1 添加依赖

  在订单工程工程的pom.xml中添加如下依赖

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

1.2 开启Feign功能

  使用@EnableFeignClients开启Feign功能

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

1.3 创建Feign客户端

  在注解@FeignClient注解中,“cloud-payment-service”是服务名,使用这个名字来从Eureka服务列表中得到相应的服务,来创建LoadBalancer客户端,也可以使用url属性,指定服务的URL。

@FeignClient(value = "cloud-payment-service")
public interface PaymentClient {

    @GetMapping("/payment/{id}")
    public Payment payment(@PathVariable("id") Integer id);
}

1.4 OrderController

    @Autowired
    private PaymentClient paymentClient;

    @GetMapping("/feign/payment/{id}")
    public ResponseEntity<Payment> getPaymentByFeign(@PathVariable("id") Integer id) {
        Payment payment = paymentClient.payment(id);

        return ResponseEntity.ok(payment);
    }

1.5 启动并测试

  分别启动支付服务9000端口,9001端口,订单服务,访问http://localhost:9002/order/feign/payment/123,执行效果如图所示。

image.png

多次执行发现9000、9001,顺序显示。因此得知Feign集成了负载均衡LoadBalancer组件

2. 超时配置

  通过分析上述案例的执行现象,得到结论OpenFeign集成了负载均衡组件LoadBalancer,OpenFeign提供了2个超时参数。

  • connectTimeout防止由于服务器处理时间长而阻塞调用者。
  • readTimeout 从连接建立时开始应用,在返回响应时间过长时触发。   对于所有的FeignClient配置,可以使用"default"假名,代码如下。
feign:
  client:
    config:
      default:
        connectTimeout: 5000 #防止由于服务器处理时间长而阻塞调用者
        readTimeout: 5000 #从连接建立时开始应用,在返回响应时间过长时触发

  如果只对于具体FeignClient配置,可以把default换成具体的FeignClient的名字,代码如下。

feign:
  client:
    config:
      cloud-paymen-servcie:
        connectTimeout: 5000 #防止由于服务器处理时间长而阻塞调用者
        readTimeout: 5000 #从连接建立时开始应用,在返回响应时间过长时触发

3. 集成熔断器

  Feign可以集成Spring Cloud CircuitBreaker熔断器,集成后,Feign将使用断路器包装的所有方法。具体用法如下。

3.1 添加依赖

在订单工程pom.xml中增加resilience4j熔断组件依赖

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

3.2 开启Feign的熔断器支持

application.yml中增加如下配置。

feign:
  circuitbreaker:
    enabled: true

3.3 Feign熔断降级类

Spring Cloud CircuitBreaker支持降级概念,当熔断器打开,或者调用是出现错误,则执行降级方法。@FeignClient的fallback属性指定讲解的类,注意服务降级类需要在spring容器中注册。代码如下。

package com.lxs.demo.client;

import com.lxs.entity.Payment;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "cloud-payment-service", fallback = PaymentClient.Fallback.class)
public interface PaymentClient {

    @GetMapping("/payment/{id}")
    public Payment payment(@PathVariable("id") Integer id);

    @Component
    static class Fallback implements PaymentClient {

        @Override
        public Payment payment(Integer id) {
            Payment payment = new Payment(id, "熔断降级方法返回");
            return payment;
        }
    }

}

如果想要获得熔断降级的异常信息,比如打印异常日志,则可以使用fallbackFactory属性指定。代码如下。

package com.lxs.demo.client;

import com.lxs.entity.Payment;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

//@FeignClient(name = "cloud-payment-service", fallback = PaymentClient.Fallback.class)
@FeignClient(value = "cloud-payment-service", fallbackFactory = PaymentClient.FallBackFactory.class)
public interface PaymentClient {

    @GetMapping("/payment/{id}")
    public Payment payment(@PathVariable("id") Integer id);

    @Component
    static class Fallback implements PaymentClient {

        @Override
        public Payment payment(Integer id) {
            Payment payment = new Payment(id, "熔断降级方法返回");
            return payment;
        }
    }

    @Component
    static class FallBackFactory implements FallbackFactory<Fallback> {

        @Override
        public Fallback create(Throwable cause) {
            cause.printStackTrace();
            return new Fallback();
        }
    }

}

3.4 启动并测试

启动订单服务和Eureka,此时因为没有服务提供者支付服务。执行是发生异常,熔断降级方法执行,效果如下图所示。

image.png

image.png

打印异常日志

image.png

4. 请求和响应压缩

feign:
  compression:
    request:
      enabled: true # 请求压缩
      mime-types: text/xml,application/xml,application/json # 压缩的类型
      min-request-size: 2048 # 请求最小压缩的阈值
    response:
      enabled: true #响应压缩
      useGzipDecoder: true #使用gzip解码器解码响应数据

5. Feign日志

可以配置打开Feign日志,显示Feign调用的详细信息,比如请求和响应的headersbodymetadata。具体步骤如下

5.1. 设置日志级别

Feign Logging只响应debug级别,在application.yml中配置如下。

logging:
  level:
    com.zjl: debug

5.2 配置FeignLoggerLevel

在配置类中配置Logger.Level,告诉配置类Feign需要打印的内容,具体代码如下。

@Configuration
public class FooConfiguration {
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

其中Logger.Level取值如下。

  • NONE,无日志记录(默认)。
  • BASIC, 只记录请求方法和 URL 以及响应状态码和执行时间。
  • HEADERS, 记录基本信息以及请求和响应标头。
  • FULL, 记录请求和响应的标头、正文和元数据。

image.png