詳解OpenFeign服務調(diào)用(微服務)
OpenFeign服務調(diào)用
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
HttpMessageConvertersused 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. linkFeign是一個聲明式WebService客戶端。使用Feign能讓編寫Web Service客戶端更加簡單。它的使用方法是定義一個服務接口然后在上面添加注解。Feign也支持可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支持了Spring MVC標準注解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支持負載均衡。
Feign能干什么
Feign旨在服務調(diào)用時,使編寫Java Http客戶端變得更容易。
前面在使用Ribbon+RestTemplate時,利用RestTemplate對http請求的封裝處理,形成了一套模版化的調(diào)用方法。但是在實際開發(fā)中,由于對服務依賴的調(diào)用可能不止一處,往往一個接口會被多處調(diào)用,所以通常都會針對每個微服務自行封裝一些客戶端類來包裝這些依賴服務的調(diào)用。所以,F(xiàn)eign在此基礎上做了進一步封裝,由他來幫助我們定義和實現(xiàn)依賴服務接口的定義。在Feign的實現(xiàn)下,我們只需創(chuàng)建一個接口并使用注解的方式來配置它(以前是Dao接口上面標注Mapper注解,現(xiàn)在是一個微服務接口上面標注一個Feign注解即可),即可完成對服務提供方的接口綁定,簡化了使用Spring cloud Ribbon時,自動封裝服務調(diào)用客戶端的開發(fā)量。
Feign集成了Ribbon
利用Ribbon維護了Payment的服務列表信息,并且通過輪詢實現(xiàn)了客戶端的負載均衡。而與Ribbon不同的是,通過feign只需要定義服務綁定接口且以聲明式的方法,優(yōu)雅而簡單的實現(xiàn)了服務調(diào)用。
Feign和OpenFeign兩者區(qū)別
Feign是Spring Cloud組件中的一個輕量級RESTful的HTTP服務客戶端Feign內(nèi)置了Ribbon,用來做客戶端負載均衡,去調(diào)用服務注冊中心的服務。Feign的使用方式是:使用Feign的注解定義接口,調(diào)用這個接口,就可以調(diào)用服務注冊中心的服務。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
OpenFeign是Spring Cloud在Feign的基礎上支持了SpringMVC的注解,如@RequesMapping等等。OpenFeign的@Feignclient可以解析SpringMVc的@RequestMapping注解下的接口,并通過動態(tài)代理的方式產(chǎn)生實現(xiàn)類,實現(xiàn)類中做負載均衡并調(diào)用其他服務。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
OpenFeign服務調(diào)用
接口+注解:微服務調(diào)用接口 + @FeignClient
1.新建cloud-consumer-feign-order80
2.POM
<?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>LearnCloud</artifactId>
<groupId>com.lun.springcloud</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-feign-order80</artifactId>
<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>
<!-- 引入自己定義的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.lun.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</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>
3.YML
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka, http://localhost:7002/eureka
4.主啟動
package cn.kt.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Created by tao.
* Date: 2022/7/6 23:01
* 描述:
*/
@SpringBootApplication
@EnableFeignClients // 開啟feign客戶端
public class OrderFeignMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderFeignMain80.class, args);
}
}5.業(yè)務類
業(yè)務邏輯接口+@FeignClient配置調(diào)用provider服務
新建PaymentFeignService接口并新增注解@FeignClient
import com.lun.springcloud.entities.CommonResult;
import com.lun.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 cn.kt.springcloud.controller;
import cn.kt.springcloud.entities.CommonResult;
import cn.kt.springcloud.entities.Payment;
import cn.kt.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;
/**
* Created by tao.
* Date: 2022/7/6 23:07
* 描述:
*/
@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);
}
}6.測試
先啟動2個eureka集群7001/7002
再啟動2個微服務8001/8002
啟動OpenFeign80啟動
http://localhost/consumer/payment/get/31
Feign自帶負載均衡配置項
配置對應關(guān)系如下圖:

OpenFeign超時控制
超時設置,故意設置超時演示出錯情況
1.服務提供方8001/8002故意寫暫停程序
@RestController
@Slf4j
public class PaymentController {
...
@Value("${server.port}")
private String serverPort;
...
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout()
{
// 業(yè)務邏輯處理正確,但是需要耗費3秒鐘
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return serverPort;
}
...
}
2.服務消費方80添加超時方法PaymentFeignService
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService{
...
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout();
}3.服務消費方80添加超時方法OrderFeignController
@RestController
@Slf4j
public class OrderFeignController
{
@Resource
private PaymentFeignService paymentFeignService;
...
@GetMapping(value = "/consumer/payment/feign/timeout")
public String paymentFeignTimeout()
{
// OpenFeign客戶端一般默認等待1秒鐘
return paymentFeignService.paymentFeignTimeout();
}
}4.測試:
多次刷新: http://localhost/consumer/payment/feign/timeout
將會跳出錯誤Spring Boot默認錯誤頁面,主要異常:feign.RetryableException:Read timed out executing GET http://CLOUD-PAYMENT-SERVCE/payment/feign/timeout。
OpenFeign默認等待1秒鐘,超過后報錯
YML文件里需要開啟OpenFeign客戶端超時控制
#設置feign客戶端超時時間(OpenFeign默認支持ribbon)(單位:毫秒) ribbon: #指的是建立連接所用的時間,適用于網(wǎng)絡狀況正常的情況下,兩端連接所用的時間 ReadTimeout: 5000 #指的是建立連接后從服務器讀取到可用資源所用的時間 ConnectTimeout: 5000
OpenFeign日志增強
日志打印功能
Feign提供了日志打印功能,我們可以通過配置來調(diào)整日恙級別,從而了解Feign 中 Http請求的細節(jié)。
說白了就是對Feign接口的調(diào)用情況進行監(jiān)控和輸出
日志級別
- NONE:默認的,不顯示任何日志;
- BASIC:僅記錄請求方法、URL、響應狀態(tài)碼及執(zhí)行時間;
- HEADERS:除了BASIC中定義的信息之外,還有請求和響應的頭信息;
- FULL:除了HEADERS中定義的信息之外,還有請求和響應的正文及元數(shù)據(jù)。
配置日志bean
package cn.kt.springcloud.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by tao.
* Date: 2022/7/7 00:01
* 描述:
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}YML文件里需要開啟日志的Feign客戶端
logging:
level:
# feign日志以什么級別監(jiān)控哪個接口
cn.kt.springcloud.service.PaymentFeignService: debug 打開刷新:http://localhost/consumer/payment/get/31
后臺日志查看
得到更多日志信息。

到此這篇關(guān)于OpenFeign服務調(diào)用的文章就介紹到這了,更多相關(guān)OpenFeign服務調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java兩個List<T> 求交集,差集,并集,去重后的并集
本文主要介紹了Java兩個List<T> 求交集,差集,并集,去重后的并集,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04
Java將Word文檔轉(zhuǎn)換為PDF文件的幾種常用方法總結(jié)
這篇文章主要介紹了Java將Word文檔轉(zhuǎn)換為PDF文件的四種常用方法,分別使用ApachePOI+iText、Aspose.Words?for?Java、Docx4j和JODConverter,這些庫各有優(yōu)點,但在使用時需要注意庫與Java環(huán)境的兼容性、安裝所需依賴、轉(zhuǎn)換速度和資源消耗,需要的朋友可以參考下2024-10-10
Springboot Mybatis-Plus數(shù)據(jù)庫單元測試實戰(zhàn)(三種方式)
這篇文章主要介紹了Springboot Mybatis-Plus數(shù)據(jù)庫單元測試實戰(zhàn)(三種方式),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-12-12
Java實現(xiàn)跳轉(zhuǎn)到指定頁面的方法小結(jié)
在Java中,實現(xiàn)頁面跳轉(zhuǎn)主要涉及到Web開發(fā),而這通常通過使用Java的Web框架(如Servlet、Spring MVC)來完成,下面講解一下如何在不同的Java Web框架中實現(xiàn)頁面跳轉(zhuǎn),文中有詳細的代碼示例供大家參考,需要的朋友可以參考下2024-05-05
Spring Cloud Config與Bus整合實現(xiàn)微服務配置自動刷新功能
通過整合SpringCloud Config與Spring Cloud Bus,實現(xiàn)了微服務配置的自動刷新功能,這個機制允許一個微服務實例在配置更新時通過消息總線通知其他所有實例同步更新,從而保持配置的一致性并提升系統(tǒng)的運維效率2024-10-10

