Feign的基本使用(http客戶端)
1、Feign的基本介紹
Feign 是 Netflix 開發的聲明式、模板化的HTTP客戶端, Feign可以幫助我們更快捷、優雅地調用HTTP API。
Spring Cloud Feign幫助我們定義和實現依賴服務接口的定義。在Spring Cloud feign的實現下,只需要創建一個接口并用注解方式配置它,即可完成服務提供方的接口綁定,簡化了在使用Spring Cloud Ribbon時自行封裝服務調用客戶端的開發量。
Spring Cloud對Feign進行了增強,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,從而讓Feign的使用更加方便。
1.1、Feign和RestTemplate的區別
由于我們的服務調用都是基于Http協議進行的,所以代碼中不得不使用Http相應的客戶端來進行服務間溝通。RestTemplate是Spring Web提供的Http客戶端,但是使用 RestTemplate 時代碼可讀性差,并且參數復雜 url 難維護。Feign是一個聲明式的http客戶端,其作用就是幫助我們優雅地實現http請求的發送,解決上面提到的問題。
2、Feign的基本使用
在Spring Cloud中,使用 Feign 非常簡單,創建一個接口,并在接口上添加一些注解,代碼就完成了。Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等。
下面假設在 order-service 中引入 feign,向目標服務 user-service 發起請求。(注意,order-service 和 user-service 都必須在注冊中心已經注冊,否則請求發起無法成功)
首先,在需要使用 feign 發起 http 請求的服務即 order-service 中引入 feign 的依賴,如下:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
在該服務的啟動類中添加注解 @EnableFeignClients,以此來開啟Feign的功能,如下:
@MapperScan("com.example.orderservice.mapper")
@SpringBootApplication
@EnableFeignClients //開啟Feign的功能
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
在 order-service 項目中新建一個接口類,并在接口上添加一些注解,如下:
@FeignClient("userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
feign http 客戶端主要就是基于 SpringMVC 的注解來聲明遠程調用的信息,比如上面的接口類中,通過注解指定了以下信息:
- 通過 @FeifnClient 指定目標服務名稱:userservice
- @GetMappding 指定發起的請求方式:GET
- @GetMappding 參數指定請求路徑:/user/{id}
- 成員方法指定了發起的 http 請求的參數:Long id
- 成員方法的返回值指定了 http 請求返回值的類型:User
然后就可以在代碼中通過調用該接口類的方法來發起 http 請求了,如下:
@Service public class OrderService { @Autowired OrderMapper orderMapper; @Autowired private UserClient userClient; public Order queryOrderById(Long orderId) { // 1.查詢訂單 Order order = orderMapper.findById(orderId); // 2.利用feign發起http請求 User user = userClient.findById(orderId); // 3.封裝user到Order order.setUser(user); // 4.返回 return order; } }
實際上上面的代碼相當于 RestTemplate 的以下代碼:
String url = "http://userservice/user/" + order.getUserId(); User user = restTemplate.getForObject(url, User.class);
以上就使用了 Feign 客戶端代替了 RestTemplate 來發起 http 請求,并且 Feign 無需特定指定負載均衡,默認 feign 就實現了負載均衡,也就是會自動負載均衡到目標服務的多個服務節點中。
2.1、自定義配置
可通過一些自定義配置來覆蓋 feign 的默認配置,可以修改的配置如下:

一般我們只需要配置日志級別即可。日志記錄會消耗部分性能,在調試代碼時,我們可以將日志級別改為 FULL,但是在一般情況下,日志級別都是設置為 NONE 或者 BASIC。
配置Feign日志有兩種方式:1.配置文件方式、2.java代碼方式
- 通過配置文件自定義配置
通過配置文件來自定義 feign 的日志級別,只需在配置文件添加以下配置即可:
#全局生效 feign: client: config: default: # 這里用default就是全局配置,如果是寫服務名稱,則是針對某個微服務的配置 loggerLevel: FULL # 日志級別
上面是定義了全局配置,如果想要自定義配置對具體某個目標服務發起請求時的配置的話,可以使用以下配置:
#局部生效 feign: client: config: userservice: # 這里用default就是全局配置,如果是寫服務名稱,則是針對某個微服務的配置 loggerLevel: FULL # 日志級別
- 通過Java代碼自定義配置
java代碼方式,首先需要先聲明一個Bean:
public class FeignClientConfiguration { @Bean public Logger.Level feignLogLevel(){ return Logger.Level.BASIC; } }
然后如果是全局配置,則把它放到 @EnableFeignClients 這個注解中。比如可以放在啟動類的 @EnableFeignClients 注解中,如下:
@SpringBootApplication @EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class) public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
如果是局部配置,則把它放到 @FeignClient 這個注解中。比如可以放在上面在使用 feign 時創建的接口類中,如下:
@FeignClient(value = "userservice", configuration = FeignClientConfiguration.class) public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable("id") Long id); }
3、feign 性能優化
3.1、使用連接池
Feign 底層的客戶端實現實際上是使用了 URLConnection,該 http 客戶端不支持連接池,所以我們可以通過使用 Apache HttpClient 或者 OKHttp 來使其支持連接池,達到一定的性能優化效果。
下面以使用 Apache HttpClient 為例,首先引入 HttpClient 依賴,然后再在配置文件中配置連接池即可。
如下:
<!--httpClient的依賴 --> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
在配置文件中配置連接池和相關參數,如下:
feign: httpclient: enabled: true # 開啟feign對HttpClient的支持 max-connections: 200 # 最大的連接數 max-connections-per-route: 50 # 每個路徑的最大連接數

浙公網安備 33010602011771號