SpringCloud之Feign代理,聲明式服務(wù)調(diào)用方式
將其他微服務(wù)中的服務(wù)接口,用feign在本項目中進(jìn)行調(diào)用。
Spring Cloud Feign是一套基于Netflix Feign實現(xiàn)的聲明式服務(wù)調(diào)用客戶端。它使得編寫Web服務(wù)客戶端變得更加簡單。我們只需要通過創(chuàng)建接口并用注解來配置它既可完成對Web服務(wù)接口的綁定。它具備可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的編碼器和解碼器。Spring Cloud Feign還擴(kuò)展了對Spring MVC注解的支持,同時還整合了Ribbon和Hystrix來提供均衡負(fù)載的HTTP客戶端實現(xiàn)。
對于Feign來講,其實就是一個WEB接口而已,它內(nèi)部自集成了Spring Ribbon 和Spring Hystrix 斷路器功能,也就是說可以支持自動降級和負(fù)載均衡功能??梢哉f,在內(nèi)部服務(wù)與服務(wù)之間的相互數(shù)據(jù)通信橋梁就是通過Feign來實現(xiàn)的。也就是說,我們可以像使用web service OR dubbo 一樣對其進(jìn)行聲明式的配置,這非常棒~ 在我之前的工作中,就大量的使用了Feign代理,可以說使用spring cloud 就必須要學(xué)會如何深入使用Feign代理,當(dāng)然它也非常的簡單。
引入相關(guān)依賴然后再主入口啟用注解
@EnableFeignClients //啟用代理服務(wù) @EnableCircuitBreaker //啟用斷路器

引入相關(guān)依賴然后再主入口啟用注解:@Enabl

注意:我們feign在第四個版本后需要手工的開啟斷路器功能才可以生效。
了解完Feign的基礎(chǔ)配置之后,我們當(dāng)然要開始代碼實現(xiàn)了。首先我們需要編寫一個interface,并且這個interface一定是已知的服務(wù)(也就是注冊到了Eureka上的接口服務(wù),我們在這里需要使用interface的方式進(jìn)行聲明)
@FeignClient注解就是Feign的注解聲明了,里面name屬性表示了當(dāng)前代理的服務(wù)APP NAME; fallback屬性當(dāng)然就是我們調(diào)用服務(wù)失敗的降級策略了,也就是當(dāng)網(wǎng)絡(luò)閃段、異常等調(diào)用代理服務(wù)失敗時,會根據(jù)斷路器的超時時間降級到指定的fallback所賦予的HelloServiceHystrix類中,我們可以進(jìn)行降級處理。


我們的Feign底層默認(rèn)提供了重試機(jī)制,也就是底層使用Retryer類對調(diào)用服務(wù)進(jìn)行重試調(diào)用操作,通過底層代碼我們知道默認(rèn)是每100ms去進(jìn)行調(diào)用,調(diào)用次數(shù)是5次。既然Feign集成了Ribbon 與 Hystrix ,那么必然會使用兩個超時機(jī)制,一個是Ribbon的超時時間,一個是Hystrix的超時時間.這兩個超時時間的含義截然不同,千萬要注意配置。
經(jīng)驗小結(jié): 我們可以配置Hystrix的超時時間大于Ribbon的超時時間。并且如果想進(jìn)行重試最好是Hystrix的超時時間設(shè)置為Ribbon的超時時間的倍數(shù)。
這樣我們可以進(jìn)行重試策略,如果Hystrix的超時時間小于Ribbon的超時時間,則不會重試,直接被斷路器組件對調(diào)用請求執(zhí)行請求段熔機(jī)制,服務(wù)降級。
Feign配合Ribbon、Hystrix的超時策略配置如下

1.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>com.zx.dt2b.erp</artifactId> ? ? ? ? <groupId>com.zx.dt2b.erp</groupId> ? ? ? ? <version>1.0-SNAPSHOT</version> ? ? </parent> ? ? <modelVersion>4.0.0</modelVersion> ? ? ? <artifactId>feign</artifactId> ? ? <dependencies> ? ? ? ? <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.cloud</groupId> ? ? ? ? ? ? <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> ? ? ? ? </dependency> ? ? ? ? <dependency> ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId> ? ? ? ? ? ? <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> ? ? ? ? </dependency> ? ? ? ? <dependency> ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId> ? ? ? ? ? ? <artifactId>spring-cloud-starter-feign</artifactId> ? ? ? ? </dependency> ? ? </dependencies> ? ? ? <dependencyManagement> ? ? ? ? <dependencies> ? ? ? ? ? ? <dependency> ? ? ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId> ? ? ? ? ? ? ? ? <artifactId>spring-cloud-dependencies</artifactId> ? ? ? ? ? ? ? ? <!-- <version>Dalston.SR5</version> ?--> ? ? ? ? ? ? ? ? <version>Edgware.SR4</version> ? ? ? ? ? ? ? ? <!-- <version>Finchley.SR1</version> ?--> ? ? ? ? ? ? ? ? <type>pom</type> ? ? ? ? ? ? ? ? <scope>import</scope> ? ? ? ? ? ? </dependency> ? ? ? ? </dependencies> ? ? </dependencyManagement>? ? ? ? <build> ? ? ? ? <finalName>feign</finalName> ? ? ? ? <plugins> ? ? ? ? ? ? <plugin> ? ? ? ? ? ? ? ? <groupId>org.springframework.boot</groupId> ? ? ? ? ? ? ? ? <artifactId>spring-boot-maven-plugin</artifactId> ? ? ? ? ? ? ? ? <configuration> ? ? ? ? ? ? ? ? ? ? <mainClass>com.zx.dt2b.FeignApplication</mainClass> ? ? ? ? ? ? ? ? </configuration> ? ? ? ? ? ? </plugin> ? ? ? ? </plugins> ? ? </build> ? </project>
2.主入口
package com.zx.dt2b;?
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
?
@EnableFeignClients?? ??? ?//啟用代理服務(wù)
@EnableCircuitBreaker?? ?//啟用斷路器
@EnableDiscoveryClient?? ?//標(biāo)識具體的一個服務(wù),需要向注冊中心注冊
@SpringBootApplication?? ?//SpringBoot 核心配置
public class FeignApplication {
?
?? ?public static void main(String[] args) {?
?? ??? ?SpringApplication.run(FeignApplication.class, args);
?? ?}?
}3.配置文件
feign: ? hystrix: ? ? enabled: true ?#開啟降級 ? compression: ? ? request: ? ? ? min-request-size: 2048 ? ? ? mime-types: ? ? ? ? - text/html, application/xml, application/json spring: ? application: ? ? name: feign-consumer ? cloud: ? ? loadbalancer: ? ? ? retry: ? ? ? ? enabled: true ? server: ? context-path: / ? port: 7005 ? eureka: ? client: ? ? service-url: ? ? ? defaultZone: http://eureka1:8001/eureka ? feign: ? hystrix: ? ? enabled: true ? compression: ? ? request: ? ? ? min-request-size: 2048 ? ? ? mime-types: ? ? ? ? - text/html, application/xml, application/json ? ##設(shè)置斷路器的超時時間 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 10000 ? ##微服務(wù)的請求配置 customer-service: ? ConnectTimeout: 10000 ? ReadTimeout: 3000 ? ribbon: ? ? OkToRetryOnAllOperations: true ##對所有的請求都進(jìn)行重試 ? ? MaxAutoRetriesNextServer: 1 ##切換實例的次數(shù) ? ? MaxAutoRetries: 2 ? ?##對當(dāng)前實例重試的次數(shù)
4.業(yè)務(wù)代碼與實現(xiàn)
@FeignClient(name="provider-service", fallback= IndexFeignFailback.class)
name表示微服務(wù)名稱:前端直接從本項目訪問其他項目服務(wù)接口
失敗后IndexFeignFailback中對應(yīng)的接口,進(jìn)行降級。
代理服務(wù)中異常等要保持一致
package com.zx.dt2b.feign;?
import com.zx.dt2b.feign.hystrix.IndexFeignFailback;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
?
@FeignClient(name="customer-service", fallback= IndexFeignFailback.class)
public interface IndexFeignClient {
?
?? ?@RequestMapping(value="/customerservice/index", method = {RequestMethod.GET})
?? ?public String hello() throws Exception;
?
?? ?@RequestMapping(value="/customerservice/hi", method = {RequestMethod.GET})
?? ?public String hi() throws InterruptedException;
}package com.zx.dt2b.feign.hystrix;?
import com.zx.dt2b.feign.IndexFeignClient;
import org.springframework.stereotype.Component;
?
@Component
public class IndexFeignFailback implements IndexFeignClient {
?
?? ?@Override
?? ?public String hello() throws Exception {
?? ??? ?return "-----hello接口的降級方法!--------";
?? ?}
?
?? ?@Override
?? ?public String hi() throws InterruptedException {
?? ??? ?return "-----hi接口的降級方法!--------";
?? ?}?
}5.controller測試
package com.zx.dt2b.api;?
import com.zx.dt2b.feign.IndexFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
?
@RestController
public class ConsumerController {
?
?? ?@Autowired
?? ?private IndexFeignClient indexFeignClient;
?
?? ?@RequestMapping(value="/feign-hello")
?? ?public String hello() throws Exception {
?? ??? ?return indexFeignClient.hello();
?? ?}
?
?? ?@RequestMapping(value="/feign-hi")
?? ?public String hi() throws InterruptedException {
?? ??? ?return indexFeignClient.hi();
?? ?}
}以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot REST國際化的實現(xiàn)代碼
本文我們將討論如何在現(xiàn)有的Spring Boot項目中添加國際化。只需幾個簡單的步驟即可實現(xiàn)Spring Boot應(yīng)用的國際化,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10
Windows安裝兩個或多個JDK并實現(xiàn)自由切換的方法
最近新接手一個項目,啟動的時候,發(fā)現(xiàn)有些jar和現(xiàn)在正在使用的JDK版本不一致,一直啟動有問題,想著就多裝一個JDK,由于為了保證java的運行環(huán)境和編譯環(huán)境保持一致,就需要我們設(shè)置jdk的環(huán)境變量,所以本文給大家介紹了Windows安裝兩個或多個JDK并實現(xiàn)自由切換的方法2025-03-03
Servlet連接數(shù)據(jù)庫實現(xiàn)用戶登錄的實現(xiàn)示例
本文主要介紹了Servlet連接數(shù)據(jù)庫實現(xiàn)用戶登錄的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
MybatisPlus+Postgresql整合的幾個坑及解決
這篇文章主要介紹了MybatisPlus+Postgresql整合的幾個坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
Java從內(nèi)存角度帶你理解數(shù)組名實質(zhì)是個地址的論述
這篇文章主要介紹了Java如何從內(nèi)存解析的角度理解“數(shù)組名實質(zhì)是一個地址”,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09
spring中BeanPostProcessor的作用和使用注意事項
在Spring框架中,BeanPostProcessor?是一個核心擴(kuò)展接口,允許你在Bean實例化的過程中插入自定義邏輯,本文給大家介紹spring中BeanPostProcessor的作用,感興趣的朋友一起看看吧2025-04-04
Java中public關(guān)鍵字用法詳細(xì)講解
這篇文章主要給大家介紹了關(guān)于Java中public關(guān)鍵字用法的相關(guān)資料,public關(guān)鍵字是和訪問權(quán)限相關(guān)的,它所修飾的方法對所有類都是可以訪問的,需要的朋友可以參考下2023-09-09
關(guān)于springboot響應(yīng)式編程整合webFlux的問題
在springboot2.x版本中提供了webFlux依賴模塊,該模塊有兩種模型實現(xiàn):一種是基于功能性端點的方式,另一種是基于SpringMVC注解方式,今天通過本文給大家介紹springboot響應(yīng)式編程整合webFlux的問題,感興趣的朋友一起看看吧2022-01-01
java巧用@Convert實現(xiàn)表字段自動轉(zhuǎn)entity
本文主要介紹了java巧用@Convert實現(xiàn)表字段自動轉(zhuǎn)entity,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07

