简述

OpenFeign是一个声明式的web服务客户端,只需创建一个Rest接口并在该接口上添加注解@FeignClient即可

其本质上就是当前微服务之间调用的事实标准

OpenFeign同时还集成了Spring Cloud LoadBalancer,可以在使用OpenFeign时提供Http客户端的负载均衡,也可以基础阿里巴巴Sentinel来提供熔断、降级等功能


通用步骤

总流程图


服务提供者

接口控制器

package com.xlyo.openfeignlearnprovider.controller;
​
import jakarta.annotation.PostConstruct;
import org.springframework.web.bind.annotation.*;
​
import java.util.ArrayList;
import java.util.List;
​
@RestController
@RequestMapping("/pay")
public class PayController {
    private static final List<String> payList = new ArrayList<>();
​
    @PostConstruct
    public void init() {
        payList.addAll(List.of("支付宝", "微信", "银联"));
    }
​
    @GetMapping("/list")
    public List<String> getPayList() {
        return payList;
    }
​
    @PostMapping("/add")
    public String add(@RequestParam("item") String item) {
        payList.add(item);
        return "ok";
    }
}

公共依赖

服务提供者抽取供其它微服务调用的接口

pom依赖

这里只放一些相关的代码

<properties>
    <spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
​
<dependencies>
    <!-- OpenFeign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>
​
<!-- 依赖管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
​
<!-- Maven私服发布管理 -->
<distributionManagement>
    <repository>
        <id>xlyo-cloud</id>
        <url>http://47.116.120.48:45502/repository/xlyo-cloud/</url>
    </repository>
</distributionManagement>
​
<!-- 构建 -->
<build>
    <plugins>
        <!-- 打包Jar插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.4.1</version>
        </plugin>
​
        <!--发布代码Jar插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <version>3.1.2</version>
        </plugin>
​
        <!--发布源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
​
    </plugins>
</build>

抽取接口

package com.xlyo.openfeignlearncommon;
​
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
​
import java.util.List;
​
@Component
@FeignClient(name = "pay-service", url = "http://localhost:8082")
public interface PayFeignApi {
​
    @GetMapping("/pay/list")
    List<String> getPayList();
​
    @PostMapping("/pay/add")
    String add(@RequestParam("item") String item);
}
@Component

用于注册到springIOC容器中

@FeignClient

名称

说明

示例

name

该接口对应的服务名称(配置了服务注册发现中心时通过该服务名称访问)

pay-service

url

该服务提供者的URL地址(默认上述name进行访问)

http://localhost:8082


服务消费者

pom依赖

这里只放一些相关的代码

<properties>
    <spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
​
<!-- Maven私服 -->
<repositories>
    <repository>
        <id>xlyo-cloud</id>
        <url>http://47.116.120.48:45502/repository/xlyo-cloud/</url>
    </repository>
</repositories>
​
<dependencies>
    <!-- 引用私服上的Jar包 - 公共依赖 -->
    <dependency>
        <groupId>com.xlyo</groupId>
        <artifactId>open-feign-learn-common</artifactId>
        <version>1.0</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>
​
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

主启动类

package com.xlyo.openfeignlearnconsumer;
​
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
​
@EnableFeignClients("com.xlyo.openfeignlearncommon")
@SpringBootApplication
public class OpenFeignLearnConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(OpenFeignLearnConsumerApplication.class, args);
    }
}
@EnableFeignClients

需要指定OpenFeign的扫描包路径


接口控制器

package com.xlyo.openfeignlearnconsumer.controller;
​
import com.xlyo.openfeignlearncommon.PayFeignApi;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
import java.util.List;
​
@RestController
@RequestMapping("/managePay")
public class ManagePayController {
    @Resource
    private PayFeignApi payService;
​
    @GetMapping("/list")
    public List<String> list() {
        return payService.getPayList();
    }
​
    @GetMapping("/add")
    public String add(String item) {
        return payService.add(item);
    }
}

测试

现在通过访问服务消费者提供的接口就可以间接操作服务提供者

GET http://localhost:8081/managePay/add?item=%E9%BB%91%E9%87%91%E5%8D%A1

现在通过服务提供者看看上述调用有没有成功添加数据

GET http://localhost:8082/pay/list


超时控制

OpenFeign的默认超时时间是60秒超时直接抛异常

我们可以配置其超时时间,其有2个超时时间

  • connectTimeout:连接超时时间

  • readTimeout:请求处理超时时间

全局配置

spring:
  cloud:
    openfeign:
      client:
        config:
          default:
            connect-timeout: 3000   # 连接超时时间,这里为3秒
            read-timeout: 3000  # 请求处理超时时间,这里为3秒

指定配置

单个服务调用的超时配置

如果同时指定default,则单个配置会覆盖默认/全局配置

spring:
  cloud:
    openfeign:
      client:
        config:
          pay-service:  # 这里的名字要和公共依赖中接口的名字一致
            connect-timeout: 5000   # 连接超时时间,这里为5秒
            read-timeout: 5000  # 请求处理超时时间,这里为5秒

上述的pay-service公共依赖@FeignClientname相同

@FeignClient(name = "pay-service", url = "http://localhost:8082")
public interface PayFeignApi {
    ...
}

重试机制

默认的重试是关闭的,其默认值为Retryer.NEVER_RETRY

要开启就需要进行手动配置

package com.xlyo.openfeignlearnconsumer.config;
​
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
@Configuration
public class FeignConfiguration {
​
    /**
     * 设置Feign的重试策略
     */
    @Bean
    public Retryer feignRetryer() {
        // return Retryer.NEVER_RETRY; // 默认禁用重试
        
        // 初始间隔100ms,重试最大间隔1s,最大重试次数3
        return new Retryer.Default(100, 1, 3);
    }
}

性能优化

OpenFiegn默认使用JDK自带的HttpURLConnection发送HTTP请求,其没有连接池,性能和效率低下

需要使用Apache HttpClient5进行替换

<!-- OpenFeign替换HttpClient5 -->
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-hc5 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-hc5</artifactId>
    <version>13.2.1</version>
</dependency>
spring:
  cloud:
    openfeign:
      httpclient:
        hc5:
          enabled: true

请求响应压缩

请求响应的内容进行压缩,以缩减少通信过程中的性能损耗

spring:
  cloud:
    openfeign:
      compression:
        request:
          enabled: true     # 开启请求压缩
          mime-types: text/xml,application/xml,application/json   # 触发请求压缩的类型
          min-request-size: 2048    # 最小触发请求压缩的大小
        response:
          enabled: true     # 开启响应压缩

日志打印

通过调整日志级别,对其接口调用情况进行监控和输出

  • NONE:默认,不显示如何日志;

  • BASIC:仅记录请求方法、URL、响应状态码和执行时间;

  • HEADERS:除了BASIC中的信息外,还有请求和响应头的信息;

  • FULL:除了HEADERS中的信息外,还有请求和响应头的正文及元数据;

package com.xlyo.openfeignlearnconsumer.config;
​
import feign.Logger;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
@Configuration
public class FeignConfiguration {
​
    /**
     * 设置Feign日志级别
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}
logging:
  level:
    com:    # 全包名
      xlyo:
        openfeignlearncommon:
          PayFeignApi: DEBUG    # 设置要监控的公共依赖接口

规则,就是用来打破的( ̄へ ̄)!