java springCloud总结-feign

时间:2025-08-27 14:30:01来源:互联网

下面小编就为大家分享一篇java springCloud总结-feign,具有很好的参考价值,希望对大家有所帮助。

概述

Spring Cloud Feign是一个声明式的HTTP客户端,你可以通过编写接口的方式来定义服务之间的通信接口。Feign会根据接口定义自动生成实现类,无需手动编写HTTP请求的代码。

可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。

 

声明式:指的是通过使用注解和编写接口的方式来定义服务之间的通信接口,Feign能够自动生成实现类,将接口方法映射为HTTP请求,并处理请求的发送和响应的处理。而无需手动编写HTTP请求的代码。

功能

声明式的http客户端:以Java接口注解的方式调用Http请求

负载均衡:与Ribbon(或其他负载均衡框架)集成,使用负载均衡的前提是先与服务发现的框架集成,在服务发现的基础上才能根据负载均衡框架做负载均衡

服务发现:与Eureka(或其他服务发现框架如nacos)集成, Feign会自动从服务注册中心获取可用的服务实例(根据@FeignClient的name属性)。

错误处理:Feign提供了默认的错误处理机制,可以处理常见的HTTP错误状态码。你可以通过自定义的错误解码器(ErrorDecoder)来处理特定的错误响应。

日志记录:Feign提供了日志记录的功能,可以记录请求和响应的详细信息,方便调试和排查问题。

 

错误处理功能说明

以下是一些常见的错误处理功能:

1. 异常转换:当服务调用失败或返回错误状态码时,Feign可以将底层的HTTP异常转换为更具体的异常类型。这样,你可以根据不同的异常类型来处理不同的错误情况。例如,Feign可以将HTTP 404错误转换为FeignException.NotFound异常,HTTP 500错误转换为FeignException.InternalServerError异常等。

2. 自定义错误处理器:你可以通过实现ErrorDecoder接口来自定义错误处理器。该接口允许你根据不同的错误响应来自定义异常的生成方式。你可以在自定义错误处理器中处理特定的错误响应,并将其转换为适合你的应用程序的异常类型。

3. Fallback机制:Feign还提供了一种回退机制,即当服务调用失败时,可以执行备用逻辑。你可以为Feign客户端接口定义一个回退实现类,该类实现了与原始接口相同的方法,并提供备用的逻辑。当服务调用失败时,Feign将调用回退实现类中的对应方法,以执行备用逻辑。

4. 全局错误处理器:你可以通过实现ErrorDecoder接口的decode方法来定义全局的错误处理器。该方法将在所有Feign客户端接口的错误处理中被调用,以处理通用的错误情况。你可以在全局错误处理器中定义如何处理特定的错误响应,并将其转换为适合你的应用程序的异常类型。

通过这些错误处理功能,你可以更好地处理与服务通信时可能出现的异常情况,提高应用程序的可靠性和容错性。

优先级说明:fallback机制>异常转换>自定义错误处理器>全局错误处理器

 

异常转换功能说明:默认是开启的,Feign使用了feign.codec.ErrorDecoder接口来处理异常转换。默认情况下,Feign使用feign.codec.ErrorDecoder.Default作为默认的错误处理器。该默认处理器会根据不同的HTTP状态码来生成相应的Feign异常类型。

Fallback机制说明:

1. 定义回退实现类:首先,你需要在调用端为Feign客户端接口定义一个回退实现类。回退实现类实现了与原始接口相同的方法,并提供备用的逻辑。回退实现类可以在服务调用失败时被调用,以执行备用逻辑。

   @Component
   public class YourFeignClientFallback implements YourFeignClient {

       @Override
       public String yourMethod() {
           // 执行备用逻辑
           return "Fallback response";
       }
   }

2. 启用回退机制:为了启用fallback机制,你需要在Feign客户端接口上使用@FeignClient注解的fallback属性,将回退实现类指定为回退逻辑的实现。

   @FeignClient(name = "your-service", fallback = YourFeignClientFallback.class)
   public interface YourFeignClient {

       @GetMapping("/your-endpoint")
       String yourMethod();
   }

3.使用Feign客户端:跟正常调用feign客户端一样

   @RestController
   public class YourController {

       @Autowired
       private YourFeignClient yourFeignClient;

       @GetMapping("/your-api")
       public String yourApi() {
           return yourFeignClient.yourMethod();
       }
   }

 

全局错误处理器说明:

Feign提供了一种全局错误处理器的机制,允许你在所有Feign客户端接口的错误处理中定义通用的错误处理逻辑。通过实现ErrorDecoder接口的decode方法,你可以自定义全局错误处理器。

   public class GlobalErrorDecoder implements ErrorDecoder {

       @Override
       public Exception decode(String methodKey, Response response) {
           // 处理错误响应并返回适当的异常类型
           // ...
           return new CustomException("Custom error message");
       }
   }

册全局错误处理器:为了将全局错误处理器应用于所有的Feign客户端接口,你需要在Feign客户端配置类中注册全局错误处理器。

   @Configuration
   public class FeignClientConfiguration {

       @Bean
       public ErrorDecoder errorDecoder() {
           return new GlobalErrorDecoder();
       }
   }

日志记录功能说明

日志记录功能,可以帮助你在调试和排查问题时更好地了解Feign的请求和响应信息

启用日志记录:要启用Feign的日志记录功能,你需要在应用程序的配置文件中添加以下配置:

logging.level.<feign-client-name>=<log-level>

日志级别,例如INFO、DEBUG、ERROR等

这种方式适用于希望为特定的Feign客户端设置不同的日志级别的情况。

Feign日志类型配置

logging.level.feign.<logger-name>=<log-level>

其中<logger-name>是Feign内部日志记录器的名称。
以下是一些常见的Feign内部日志记录器名称:
- feign.Logger:Feign的请求和响应日志记录器。
- feign.Retryer:Feign的重试日志记录器。
- feign.Contract:Feign的契约日志记录器。
- feign.Client:Feign的客户端日志记录器。

日志级别,例如INFO、DEBUG、ERROR等

全局feign日志配置

feign.client.config.default.loggerLevel=<log-level>

日志级别:你可以根据需要设置不同的日志级别,以控制日志记录的详细程度。常见的日志级别包括:
- NONE:不记录任何日志。
- BASIC:仅记录请求方法、URL和响应状态码。
- HEADERS:记录请求和响应的基本信息,包括头部信息。
- FULL:记录请求和响应的详细信息,包括头部、正文和元数据。

该级别将应用于所有的Feign客户端。这种方式适用于希望统一设置所有Feign客户端的日志级别的情况。

 

使用

添加依赖

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

被调用方服务B编写接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ServiceBController {

    @GetMapping("/api/data")
    public String data() {
        return "data";
    }
}

调用发起方服务A, 在Spring Boot的配置类上添加@EnableFeignClients注解来启用Feign客户端。这个注解告诉Spring Boot应用程序扫描并创建Feign客户端接口的代理实现类,以便进行服务调用。

被调用方服务B的启动类上不需要使用@EnableFeignClients注解

@SpringBootApplication
@EnableFeignClients
public class YourApplication {

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

调用发起方服务A定义调用服务B的通信接口

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "serviceB", url = "http://localhost:8081")
public interface ServiceBFeignClient {

    @GetMapping("/api/data")
    String getDataFromServiceB();
}

使用@FeignClient注解来指定Feign客户端的名称和服务的URL。

name属性指定了客户端的名称(配置成在注册中心注册的名字)

url属性指定了服务的URL(url一般用于调试,可以手动指定调用的地址,如果使用注册中心使用name指定注册的名字即可,不用配置url)。如果服务没有跟服务发现框架(如nacos,Eureka)集成,可以使用url来指定调用的地址

 服务端

 

原理

当应用启动时,Feign会根据接口定义自动生成一个代理对象。这个代理对象实现了接口中定义的方法,并将方法调用转换为HTTP请求。

当你调用代理对象的方法时,Feign会将方法调用转换为HTTP请求,并发送给目标服务。Feign使用底层的HTTP客户端(如OkHttp或HttpClient)来发送请求。

目标服务接收到请求后,会处理请求并返回响应。Feign会将响应转换为相应的Java对象,并返回给调用方。

@EnableFeignClients说明

定义在服务的调用方的启动上,这个注解告诉Spring Boot应用程序扫描并创建Feign客户端接口的代理实现类,以便进行服务调用。

被调用方的服务启动类型不需要指定

@FeignClient说明

用在调用方的feign接口上,为了被feign扫描程序发现并创建代理实现类

name指定注册中心中服务的名字

url指定要调用的服务地址

优先级:url>name

指定了url属性,Feign将直接使用该URL地址进行服务调用,而不会进行服务发现。

feign通过网关调用

要使用网关进行服务调用,你需要将Feign客户端的URL配置为网关的URL,并在网关中配置相应的路由规则。这样,当你使用Feign调用服务时,请求将经过网关进行路由和负载均衡。

 

feign对于http连接池的使用

从Feign的版本1.5.0开始,默认使用Apache HttpClient(具备连接池的功能)作为底层的HTTP客户端。在此之前的版本中,默认使用的是URLConnection(没有连接池)作为底层的HTTP客户端。

如下可以看到默认使用的httpClient

配置方式:

如果采用URLConnection的配置方式:

feign.client.default.connect-timeout 默认10s

feign.client.default.read-timeout 默认60s

如果采用Apache HttpClient的配置方式:

feign.httpclient.connection-timeout  连接超时时间默认2秒

feign.httpclient.time-to-live 存活时间默认900秒

feign.httpclient.max-connections 最大连接数默认200

如下可以看到默认的配置值

如果采用OkHttp配置方式:

feign.httpclient.connection-timeout 默认2秒

feign.client.default.read-timeout 默认60s

feign.httpclient.time-to-live 默认900秒

 

Apache HttpClient的默认连接池配置如下:
- 最大连接数(maxTotal):默认为200,表示最大同时可以建立的连接数。
- 每个路由的最大连接数(defaultMaxPerRoute):默认为20,表示对于每个目标主机的最大连接数限制。
- 连接的存活时间(keepAliveTime):默认为无限制,即连接可以一直保持活动状态。

如果你希望自定义Feign的连接池配置,可以通过创建一个HttpClient的Bean,并在该Bean中配置连接池的相关参数。以下是一个示例:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public CloseableHttpClient httpClient() {
        return HttpClientBuilder.create()
                .setMaxConnTotal(100) // 设置最大连接数
                .setMaxConnPerRoute(20) // 设置每个路由的最大连接数
                .build();
    }
}

在Feign客户端接口上使用@Configuration注解来指定使用自定义的连接池配置:

@FeignClient(name = "example", configuration = FeignConfig.class)
public interface ExampleClient {
    // 接口方法定义
}

如果你使用的是其他的HTTP客户端,例如OkHttp,那么连接池的配置方式可能会有所不同。你可以根据具体的HTTP客户端文档来了解如何配置连接池。

 

重试说明

默认feign的重试机制的关闭的

如果要开启重试

添加依赖:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

配置重试策略:

全局重试配置(如果所有feign接口都要重试就配置这个)在你的应用程序的配置类中,创建一个Retryer的Bean,并配置重试策略。以下是一个示例:

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

   @Configuration
   public class FeignConfig {

       @Bean
       public Retryer feignRetryer() {
           return new Retryer.Default(1000, 3000, 3); // 最大重试次数为3,初始间隔为1000毫秒,最大间隔为3000毫秒
       }
   }

部分重试配置(只对部分接口进行设置重试就配置这个),使用了@Retryable注解来定义重试策略。maxAttempts属性指定了最大重试次数,backoff属性指定了重试的间隔时间。

   import org.springframework.cloud.openfeign.FeignClient;
   import org.springframework.retry.annotation.Retryable;
   import org.springframework.web.bind.annotation.GetMapping;

   @FeignClient(name = "example")
   public interface ExampleFeignClient {

       @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000, maxDelay = 3000))
       @GetMapping("/example")
       String getExample();
   }

 

启用重试机制:在Feign客户端接口上使用@EnableRetry注解来启用重试机制。以下是一个示例: