詳解OpenFeign服務(wù)調(diào)用(微服務(wù))
OpenFeign服務(wù)調(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
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. linkFeign是一個聲明式WebService客戶端。使用Feign能讓編寫Web Service客戶端更加簡單。它的使用方法是定義一個服務(wù)接口然后在上面添加注解。Feign也支持可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支持了Spring MVC標(biāo)準(zhǔn)注解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支持負(fù)載均衡。
Feign能干什么
Feign旨在服務(wù)調(diào)用時,使編寫Java Http客戶端變得更容易。
前面在使用Ribbon+RestTemplate時,利用RestTemplate對http請求的封裝處理,形成了一套模版化的調(diào)用方法。但是在實際開發(fā)中,由于對服務(wù)依賴的調(diào)用可能不止一處,往往一個接口會被多處調(diào)用,所以通常都會針對每個微服務(wù)自行封裝一些客戶端類來包裝這些依賴服務(wù)的調(diào)用。所以,F(xiàn)eign在此基礎(chǔ)上做了進一步封裝,由他來幫助我們定義和實現(xiàn)依賴服務(wù)接口的定義。在Feign的實現(xiàn)下,我們只需創(chuàng)建一個接口并使用注解的方式來配置它(以前是Dao接口上面標(biāo)注Mapper注解,現(xiàn)在是一個微服務(wù)接口上面標(biāo)注一個Feign注解即可),即可完成對服務(wù)提供方的接口綁定,簡化了使用Spring cloud Ribbon時,自動封裝服務(wù)調(diào)用客戶端的開發(fā)量。
Feign集成了Ribbon
利用Ribbon維護了Payment的服務(wù)列表信息,并且通過輪詢實現(xiàn)了客戶端的負(fù)載均衡。而與Ribbon不同的是,通過feign只需要定義服務(wù)綁定接口且以聲明式的方法,優(yōu)雅而簡單的實現(xiàn)了服務(wù)調(diào)用。
Feign和OpenFeign兩者區(qū)別
Feign是Spring Cloud組件中的一個輕量級RESTful的HTTP服務(wù)客戶端Feign內(nèi)置了Ribbon,用來做客戶端負(fù)載均衡,去調(diào)用服務(wù)注冊中心的服務(wù)。Feign的使用方式是:使用Feign的注解定義接口,調(diào)用這個接口,就可以調(diào)用服務(wù)注冊中心的服務(wù)。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
OpenFeign是Spring Cloud在Feign的基礎(chǔ)上支持了SpringMVC的注解,如@RequesMapping等等。OpenFeign的@Feignclient可以解析SpringMVc的@RequestMapping注解下的接口,并通過動態(tài)代理的方式產(chǎn)生實現(xiàn)類,實現(xiàn)類中做負(fù)載均衡并調(diào)用其他服務(wù)。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
OpenFeign服務(wù)調(diào)用
接口+注解:微服務(wù)調(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> <!--一般基礎(chǔ)通用配置--> <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è)務(wù)類
業(yè)務(wù)邏輯接口+@FeignClient配置調(diào)用provider服務(wù)
新建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個微服務(wù)8001/8002
啟動OpenFeign80啟動
http://localhost/consumer/payment/get/31
Feign自帶負(fù)載均衡配置項
配置對應(yīng)關(guān)系如下圖:
OpenFeign超時控制
超時設(shè)置,故意設(shè)置超時演示出錯情況
1.服務(wù)提供方8001/8002故意寫暫停程序
@RestController @Slf4j public class PaymentController { ... @Value("${server.port}") private String serverPort; ... @GetMapping(value = "/payment/feign/timeout") public String paymentFeignTimeout() { // 業(yè)務(wù)邏輯處理正確,但是需要耗費3秒鐘 try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } return serverPort; } ... }
2.服務(wù)消費方80添加超時方法PaymentFeignService
@Component @FeignClient(value = "CLOUD-PAYMENT-SERVICE") public interface PaymentFeignService{ ... @GetMapping(value = "/payment/feign/timeout") public String paymentFeignTimeout(); }
3.服務(wù)消費方80添加超時方法OrderFeignController
@RestController @Slf4j public class OrderFeignController { @Resource private PaymentFeignService paymentFeignService; ... @GetMapping(value = "/consumer/payment/feign/timeout") public String paymentFeignTimeout() { // OpenFeign客戶端一般默認(rèn)等待1秒鐘 return paymentFeignService.paymentFeignTimeout(); } }
4.測試:
多次刷新: http://localhost/consumer/payment/feign/timeout
將會跳出錯誤Spring Boot默認(rèn)錯誤頁面,主要異常:feign.RetryableException:Read timed out executing GET http://CLOUD-PAYMENT-SERVCE/payment/feign/timeout
。
OpenFeign默認(rèn)等待1秒鐘,超過后報錯
YML文件里需要開啟OpenFeign客戶端超時控制
#設(shè)置feign客戶端超時時間(OpenFeign默認(rèn)支持ribbon)(單位:毫秒) ribbon: #指的是建立連接所用的時間,適用于網(wǎng)絡(luò)狀況正常的情況下,兩端連接所用的時間 ReadTimeout: 5000 #指的是建立連接后從服務(wù)器讀取到可用資源所用的時間 ConnectTimeout: 5000
OpenFeign日志增強
日志打印功能
Feign提供了日志打印功能,我們可以通過配置來調(diào)整日恙級別,從而了解Feign 中 Http請求的細節(jié)。
說白了就是對Feign接口的調(diào)用情況進行監(jiān)控和輸出
日志級別
- NONE:默認(rèn)的,不顯示任何日志;
- BASIC:僅記錄請求方法、URL、響應(yīng)狀態(tài)碼及執(zhí)行時間;
- HEADERS:除了BASIC中定義的信息之外,還有請求和響應(yīng)的頭信息;
- FULL:除了HEADERS中定義的信息之外,還有請求和響應(yīng)的正文及元數(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服務(wù)調(diào)用的文章就介紹到這了,更多相關(guān)OpenFeign服務(wù)調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Sax解析xml_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了Sax解析xml,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08解決SpringBoot項目使用多線程處理任務(wù)時無法通過@Autowired注入bean問題
這篇文章主要介紹了SpringBoot項目使用多線程處理任務(wù)時無法通過@Autowired注入bean問題的解決方法,需要的朋友可以參考下2018-09-09SpringBoot環(huán)境搭建及第一個程序運行(小白教程)
這篇文章主要介紹了SpringBoot環(huán)境搭建及第一個程序運行,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息
這篇文章主要介紹了Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10