10-SpringCloud OpenFeign

本文详细介绍了SpringCloud OpenFeign的使用,包括其作为声明式WebService客户端简化服务调用,集成Ribbon实现负载均衡,以及如何配置超时控制和日志增强功能。通过实例展示了如何创建Feign客户端接口,配置YML文件以调整超时时间和日志级别,最后展示了日志增强后的效果。

OpenFeign基础知识

官方文档

GitHub地址

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign. link

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

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

Feign和OpenFeign两者区别

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

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

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

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

OpenFeign服务调用

接口+注解:微服务调用接口 + @FeignClient

新建80工程

新建cloud-consumer-feign-order80

修改POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.dance.springcloud</artifactId>
        <groupId>com.dance</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-feign-order80</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- dependent on common modules -->
        <dependency>
            <groupId>com.dance</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--一般基础通用配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

新建yml配置

server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

新建主启动类

package com.dance.springcloud;

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

@SpringBootApplication
// 开启Feign客户端
@EnableFeignClients
public class OrderFeignMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class, args);
    }
}

新建Service

业务逻辑接口+@FeignClient配置调用provider服务

新建PaymentFeignService接口并新增注解@FeignClient

package com.dance.springcloud.service;

import com.dance.springcloud.entities.CommonResult;
import com.dance.springcloud.entities.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;


@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);

}

新建Controller

package com.dance.springcloud.controller;

import com.dance.springcloud.entities.CommonResult;
import com.dance.springcloud.entities.Payment;
import com.dance.springcloud.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.RestController;

import javax.annotation.Resource;

@RestController
@Slf4j
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);
    }

}

测试

  1. 启动Eureka集群
  2. 启动提供者集群
  1. 启动Feign消费者
  2. 测试
  1. http://localhost/consumer/payment/get/1

Feign自带负载均衡配置项

OpenFeign超时控制

超时设置,故意设置超时演示出错情况,应为在微服务中,服务之间的调用有时候会因为网络的延迟,业务处理量大,等待时间长的问题,肯定是要处理超时的

修改提供者Controller

8001和8002两个服务Controller都添加接口,不然应为负载的问题会报错,找不到

@RestController
@Slf4j
public class PaymentController {
    
      ................

    @GetMapping(value = "/payment/feign/timeout")
    public String paymentFeignTimeout() {
        // 业务逻辑处理正确,但是需要耗费3秒钟
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return serverPort;
    }
            
        ...............
}

修改消费者Service

package com.dance.springcloud.service;

import com.dance.springcloud.entities.CommonResult;
import com.dance.springcloud.entities.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;


@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
    @GetMapping(value = "/payment/feign/timeout")
    public String paymentFeignTimeout();
}

修改消费者Controller

package com.dance.springcloud.controller;

import com.dance.springcloud.entities.CommonResult;
import com.dance.springcloud.entities.Payment;
import com.dance.springcloud.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.RestController;

import javax.annotation.Resource;

@RestController
@Slf4j
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);
    }

    @GetMapping(value = "/consumer/payment/feign/timeout")
    public String paymentFeignTimeout() {
        // OpenFeign客户端一般默认等待1秒钟
        return paymentFeignService.paymentFeignTimeout();
    }

}

测试

  1. 启动Eureka集群
  2. 启动提供者集群
  1. 启动OpenFeign消费者
  2. 浏览器测试
  1. http://localhost/consumer/payment/feign/timeout
  1. 将会跳出错误Spring Boot默认错误页面。

OpenFeign默认等待1秒钟,超过后报错

修改yml配置

YML文件里需要开启OpenFeign客户端超时控制

server:
  port: 80

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
#设置feign客户端超时时间(OpenFeign默认支持ribbon)(单位:毫秒)
ribbon:
  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  ReadTimeout: 5000
  #指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

再次测试:

成功~

OpenFeign日志增强

日志打印功能

Feign提供了日志打印功能,我们可以通过配置来调整日恙级别,从而了解Feign 中 Http请求的细节。

说白了就是对Feign接口的调用情况进行监控和输出

日志级别

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

配置日志Bean

package com.dance.springcloud.config;

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

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

修改yml配置

YML文件里需要开启日志的Feign客户端

logging:
  level:
    # feign日志以什么级别监控哪个接口
    com.dance.springcloud.service.PaymentFeignService: debug

后台日志查看

得到更多日志信息。

2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] <--- HTTP/1.1 200 (3185ms)
2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] connection: keep-alive
2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] content-length: 4
2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] content-type: text/plain;charset=UTF-8
2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] date: Mon, 23 Aug 2021 11:33:48 GMT
2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] keep-alive: timeout=60
2021-08-23 19:33:48.678 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] 
2021-08-23 19:33:48.679 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] 8001
2021-08-23 19:33:48.679 DEBUG 8308 --- [p-nio-80-exec-1] c.d.s.service.PaymentFeignService        : [PaymentFeignService#paymentFeignTimeout] <--- END HTTP (4-byte body)

又完成了一个组件的学习~开心心 撒花花

作者:彼岸舞

时间:2021\08\23

内容关于:Spring Cloud H版

本文属于作者原创,未经允许,禁止转发

<think> 我们被要求提供Spring Cloud OpenFeign的官方文档信息。根据引用内容,我们知道OpenFeign是一个声明式的HTTP客户端,用于简化服务间的HTTP调用。在Spring Cloud中,它集成了服务发现(如Eureka)和负载均衡(如Ribbon或Spring Cloud LoadBalancer)。 根据引用[2]和[4],我们得知在Spring Cloud项目中,我们通过`@EnableFeignClients`注解来启用Feign客户端,并通过`@FeignClient`注解来声明一个Feign客户端接口。同时,配置可以通过配置文件(如application.yml)进行。 但是,用户现在需要的是官方文档的地址。在引用[1]中,我们看到了一个GitHub地址和官方文档地址的提示,但引用中并没有给出具体的URL。 实际上,Spring Cloud OpenFeign的官方文档是Spring Cloud官方文档的一部分。我们可以根据Spring Cloud的版本,在官方网站上找到对应的文档。 通常,Spring Cloud OpenFeign的官方文档地址为: https://spring.io/projects/spring-cloud-openfeign 或者,针对特定版本的文档,例如Hoxton.SR12版本(对应Spring Cloud 2.2.x),文档地址为: https://docs.spring.io/spring-cloud-openfeign/docs/2.2.12.RELEASE/reference/html/ 由于用户没有指定Spring Cloud的版本,我们可以提供主版本和当前常用版本的文档链接。 另外,引用[1]中提到了一个GitHub地址,通常是Spring Cloud OpenFeign的GitHub仓库: https://github.com/spring-cloud/spring-cloud-openfeign 因此,我们可以这样回答: ### Spring Cloud OpenFeign 官方文档 1. **项目主页**(包含最新版本信息和概述): - [https://spring.io/projects/spring-cloud-openfeign](https://spring.io/projects/spring-cloud-openfeign) 2. **参考文档**(根据版本选择): - 最新版本:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/ - 如果您使用的是特定版本(例如Hoxton.SR12对应的2.2.x),请将URL中的版本号替换为实际版本: `https://docs.spring.io/spring-cloud-openfeign/docs/{version}/reference/html/` 3. **GitHub仓库**(源代码和问题追踪): - [https://github.com/spring-cloud/spring-cloud-openfeign](https://github.com/spring-cloud/spring-cloud-openfeign) ### 使用提示 -Spring Boot项目中,您可以通过`@EnableFeignClients`注解启用Feign客户端[^3]。 - 每个Feign客户端接口需要使用`@FeignClient(name = "service-name")`注解,其中`service-name`是服务提供者在服务注册中心(如Eureka)中注册的名称[^4]。 ### 注意事项 - 请确保您的Spring Cloud版本与OpenFeign版本兼容。通常,Spring Cloud版本与OpenFeign子项目的版本保持一致(例如Spring Cloud Hoxton.SR12对应spring-cloud-openfeign 2.2.12.RELEASE)[^1]。 --- §§相关问题§§ 1. 如何查看当前项目中使用的Spring Cloud OpenFeign版本? 2. Spring Cloud OpenFeignSpring Cloud Netflix Feign有什么区别? 3. 如何在Spring Cloud Alibaba中使用OpenFeign? </think> 以下是 Spring Cloud OpenFeign 的官方文档资源及相关使用指南: --- ### 一、官方文档地址 1. **主文档**(最新版本) [https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/](https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/) *包含完整配置、注解说明和高级特性* 2. **GitHub 仓库** [https://github.com/spring-cloud/spring-cloud-openfeign](https://github.com/spring-cloud/spring-cloud-openfeign) *源码、示例和 Issue 追踪* 3. **Spring Cloud 官方文档** [https://spring.io/projects/spring-cloud#overview](https://spring.io/projects/spring-cloud#overview) *在 "Spring Cloud OpenFeign" 部分查看集成指南* --- ### 二、核心使用步骤(基于官方文档) #### 1. 添加依赖 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.1.7</version> <!-- 最新版本 --> </dependency> ``` #### 2. 启用 Feign 客户端 ```java @SpringBootApplication @EnableFeignClients // 关键注解 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 3. 声明服务接口 ```java @FeignClient(name = "user-service") // 与服务名一致 public interface UserClient { @GetMapping("/users/{id}") User getUser(@PathVariable("id") Long id); } ``` #### 4. 配置文件示例(application.yml) ```yaml spring: cloud: openfeign: client: config: default: # 全局配置 connectTimeout: 5000 readTimeout: 10000 loggerLevel: basic user-service: # 指定服务配置 connectTimeout: 3000 ``` --- ### 三、关键特性文档目录 | **章节** | **内容** | **官方文档位置** | |----------|----------|------------------| | 服务降级 | `fallback` 和 `fallbackFactory` | Section 2.4.5 | | 自定义编码器 | 文件上传/二进制流处理 | Section 2.2.8 | | 请求拦截器 | 添加认证头等操作 | Section 2.2.9 | | 日志配置 | 四级日志级别控制 | Section 2.3.1 | | 与 Ribbon 集成 | 负载均衡配置 | Section 2.1.4 | | 错误处理 | `ErrorDecoder` 自定义 | Section 2.2.11 | --- ### 四、注意事项(官方建议) 1. **服务发现集成** 默认支持 Eureka/Nacos,需确保 `@FeignClient` 的 `name` 与注册中心的服务 ID 一致[^4] 2. **包扫描规则** 若 Feign 接口不在主启动类包路径下,需指定扫描路径: ```java @EnableFeignClients(basePackages = "com.example.clients") ``` 3. **版本兼容性** Spring Cloud 2020.0.x+ 已移除 Ribbon,需显式添加负载均衡器: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值