Spring Cloud系列之Feign

Spring Cloud系列之Eureka
Spring Cloud系列之配置中心Config
Spring Cloud系列之gateway
Spring Cloud系列之Feign
Spring Cloud系列之Hystrix
Spring Cloud系列之鏈路追蹤

簡介

feign是netfix開發(fā)的一個輕量級的restful的http服務(wù)客戶端维咸,用來發(fā)起請求萍歉、遠(yuǎn)程調(diào)用凰棉。是以java接口注解的方式調(diào)用http請求讳侨,而不用像java中通過封裝http請求報文的方式直接調(diào)用。消費者拿到服務(wù)提供者的接口溺蕉,然后像調(diào)用本地方法一樣去調(diào)用遠(yuǎn)程的接口伶丐,本質(zhì)上就是feign幫我們?nèi)プ隽朔庋b并且發(fā)起請求。更符合面向接口化的編程邏輯疯特。

  • 可以幫助我們更加便捷優(yōu)雅的調(diào)用http的API哗魂,不需要我們?nèi)テ唇觰rl通過restTmplate方式去調(diào)用遠(yuǎn)程接口

  • 并且feign支持了springMVC注解

Feign入門

Feign服務(wù)提供者搭建
  • 添加依賴
<dependencies>

    <!-- eureka client依賴 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- configClient依賴 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- feign依賴 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- 健康監(jiān)測依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!--鏈路追蹤-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
    </dependency>

</dependencies>
  • FeignClient的創(chuàng)建
/**
 * @Description:
 * @author: dy
 * @Date: 2021/11/26
 */
 //@FeignClient表明當(dāng)前類是一個feign客戶端,value指定該客戶端要請求的服務(wù)名稱(登記到注冊中心的服務(wù)提供者名稱)
@FeignClient(value = "user-service",path = UserClient.MAPPING)
public interface UserClient {
    String MAPPING = "/user-service";

    @RequestMapping(value = "/get_user_id", method = RequestMethod.GET)
    public String getUserId();

}

/**
 * @Description:
 * @author: dy
 */
@Slf4j
@RestController
@RequestMapping(UserClient.MAPPING)
public class UserResource implements UserClient {

    @Autowired
    private AppInfo appinfo;

    @Override
    public String getUserId() {
        log.info("==============請求來了===============");
        return "======111111222>>"+appinfo.getAppId();
    }
}
  • 啟動類
/**
 * @Description:
 * @author: dy
 */
@EnableDiscoveryClient //開啟Eureka客戶端發(fā)現(xiàn)功能
@SpringBootApplication
public class UserServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

}
Feign服務(wù)消費者搭建
  • 引入依賴
<dependencies>
    <!--引入user-service依賴-->
    <dependency>
        <groupId>com.dy</groupId>
        <artifactId>user-service</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <!--config-client依賴-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <!--eureka-client依賴-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--鏈路追蹤-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
    </dependency>
</dependencies>
  • 啟動類 (開啟feign客戶端功能)
/**
 * @Description:
 * @author: dy
 */
//開啟feign客戶端功能 basePackages指定要掃描的feignClient類所在包路徑
@EnableFeignClients(basePackages = {"com.dy.user.client"})
//開啟Eureka客戶端發(fā)現(xiàn)功能
@EnableDiscoveryClient
@SpringBootApplication
public class UserApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApiApplication.class, args);
    }

}
  • 使用
/**
 * @Description:
 * @author: dy
 * @Date: 2021/11/29
 */
@Slf4j
@RestController
public class UserController implements UserApi {

    @Autowired
    private UserClient userClient;

    @Override
    public String getUserInfo() {
        log.info("==========滴滴========");
        return userClient.getUserId();
    }

}

這樣完成了feign的基本使用漓雅,但是我們思考一個問題录别?如果我們同時啟動了幾個service服務(wù),那我們的api會調(diào)用哪個service呢故硅?

feign對負(fù)載均衡的支持

feign自身已經(jīng)集成了對ribbon依賴和自動配置庶灿,因此不需要我們引入額外對ribbon的依賴,可用通過在配置文件里面添加響應(yīng)的配置進(jìn)行全局的配置或者對某個服務(wù)單獨的負(fù)載均衡配置吃衅。

feign默認(rèn)的請求處理超時時長是1s,有時候肯定我們的業(yè)務(wù)處理邏輯是超過1s的腾誉,那么這些就需要我們根據(jù)自己的業(yè)務(wù)進(jìn)行相應(yīng)的配置徘层,以滿足我們對每個服務(wù)的調(diào)用需求

對單個服務(wù)的ribbon配置:

user-service:
  ribbon:
    #請求連接超時時間
    ConnectTimeout: 3000
    #請求處理超時時間
    ReadTimeout: 15000
    #對所有操作都進(jìn)行重試
    OkToRetryOnAllOperations: true
    #對當(dāng)前選中的實例重試次數(shù),不包含第一次調(diào)用
    MaxAutoRetries: 0
    #切換實例的重試次數(shù)
    MaxAutoRetriesNextServer: 0
    #負(fù)載均衡策略配置
    NFLoadBalancerRuleClassName: com.netfix.loadbalancer.RoundRobinRule

負(fù)載均衡邏輯如下:

  • 根據(jù)上面得配置利职,當(dāng)訪問超時時趣效,系統(tǒng)會再嘗試一次訪問當(dāng)前實例(次數(shù)由MaxAutoRetries配置)

  • 如果不行,就換一個實例進(jìn)行訪問猪贪,如果還不行跷敬,再換一個實例訪問(更換次數(shù)由MaxAutoRetriesNextServer這個決定)

  • 如果還不行,就返回失敗結(jié)果

Ribbon默認(rèn)的負(fù)載均衡策略是RoundRobinRule也就是輪詢热押,當(dāng)然在實際開發(fā)中我們可以根據(jù)我們服務(wù)的響應(yīng)配置進(jìn)行響應(yīng)的負(fù)載均衡策略的自定義

對全局的ribbon配置(就把我們服務(wù)的名字去掉就可以了):

ribbon:
  #請求連接超時時間
  ConnectTimeout: 3000
  #請求處理超時時間
  ReadTimeout: 15000
  #對所有操作都進(jìn)行重試
  OkToRetryOnAllOperations: true
  #對當(dāng)前選中的實例重試次數(shù)西傀,不包含第一次調(diào)用
  MaxAutoRetries: 0
  #切換實例的重試次數(shù)
  MaxAutoRetriesNextServer: 0
  #負(fù)載均衡策略配置
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

Feign的日志級別配置

Feign是http請求的客戶端斤寇,類似于瀏覽器,在請求和接受響應(yīng)的時候拥褂,可以打印出比較詳細(xì)的一些信息娘锁,比如:響應(yīng)頭、狀態(tài)碼等等

如果我們想看到Feign請求時的日志饺鹃,我們可以進(jìn)行一些配置莫秆,默認(rèn)情況下Feign的日志是沒有開啟的。

  • 在api module配置如下
/**
 * @Description:
 * @author: dy
 */
@Configuration
public class FeignConfig {

    /**
     *
     * @return
     */
    @Bean
    Logger.Level feignLevel(){
        return Logger.Level.FULL;
    }

}

LEVEL說明:

  • NONE 不顯示任何日志

  • BASIC 僅記錄請求方法悔详、URL镊屎、響應(yīng)狀態(tài)碼、執(zhí)行時間 茄螃,適用于生產(chǎn)環(huán)境

  • HEADERS 在BASIC的基礎(chǔ)上記錄請求響應(yīng)的header

  • FULL 記錄請求響應(yīng)的header杯道、body、元數(shù)據(jù) 適用于開發(fā)及測試環(huán)境

注意配置log日志級別:

logging:
  level:
    com.dy.user: debug

運行結(jié)果如下:

Feign日志結(jié)果輸出.png

Feign對熔斷器的支持

  • 在feign客戶端配置文件添加配置開啟對熔斷的支持
#開啟對hystrix的支持
feign:
  hystrix:
    enabled: true

上面我們設(shè)置了feign的超時時長設(shè)置實際上是對Ribbon的超時時長設(shè)置责蝠,但是如果開啟了對hystrix的支持党巾,hystrix還有超時時長設(shè)置,如下

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            #hystrix超時時長設(shè)置
            timeoutInMilliseconds: 5000

開啟對hystrix支持后霜医,F(xiàn)eginclient中的方法就會被進(jìn)行一個管理了齿拂,一旦出現(xiàn)問題就會進(jìn)行默認(rèn)處理也就是fallback類的方法中的處理

注意:針對超時這塊,這里有兩個超時時間:一個是ribbon的超時時間肴敛,一個是hystrix的超時時間署海,熔斷的時間就是根據(jù)兩個時間中最小的超時時間來進(jìn)行的,及最短超時時間

  • clent類
/**
 * @Description:
 * @author: dy
 */
//@FeignClient表明當(dāng)前類是一個feign客戶端医男,value指定該客戶端要請求的服務(wù)名稱(登記到注冊中心的服務(wù)提供者名稱) fallback指定回退類
@FeignClient(value = "user-service",path = UserClient.MAPPING ,fallback = UserFallback.class)
public interface UserClient {
    String MAPPING = "/user-service";

    @RequestMapping(value = "/get_user_id", method = RequestMethod.GET)
    public String getUserId();

}
  • 新建fallback方法
/**
 * @Description:  降級回退邏輯定義一個類砸狞,實現(xiàn)Feign接口,實現(xiàn)其中的接口方法镀梭,返回默認(rèn)值
 * @author: dy
 */
@Component
public class UserFallback implements UserClient {
    @Override
    public String getUserId() {
        return "-1";
    }
}

Feign對請求響應(yīng)壓縮的支持

feign支持對請求和響應(yīng)進(jìn)行GZIP壓縮刀森,以減少通信過程中的性能損耗,這里我們就不進(jìn)行過多介紹了报账。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末研底,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子透罢,更是在濱河造成了極大的恐慌榜晦,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羽圃,死亡現(xiàn)場離奇詭異乾胶,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門识窿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斩郎,“玉大人,你說我怎么就攤上這事腕扶∧蹩剑” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵半抱,是天一觀的道長脓恕。 經(jīng)常有香客問我,道長窿侈,這世上最難降的妖魔是什么炼幔? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮史简,結(jié)果婚禮上乃秀,老公的妹妹穿的比我還像新娘。我一直安慰自己圆兵,他們只是感情好跺讯,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著殉农,像睡著了一般刀脏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上超凳,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天愈污,我揣著相機與錄音,去河邊找鬼轮傍。 笑死暂雹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的创夜。 我是一名探鬼主播杭跪,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挥下!你這毒婦竟也來了揍魂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤棚瘟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后喜最,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體偎蘸,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了迷雪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片限书。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖章咧,靈堂內(nèi)的尸體忽然破棺而出倦西,到底是詐尸還是另有隱情,我是刑警寧澤赁严,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布扰柠,位于F島的核電站,受9級特大地震影響疼约,放射性物質(zhì)發(fā)生泄漏卤档。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一程剥、第九天 我趴在偏房一處隱蔽的房頂上張望劝枣。 院中可真熱鬧,春花似錦织鲸、人聲如沸舔腾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稳诚。三九已至,卻和暖如春盾饮,著一層夾襖步出監(jiān)牢的瞬間采桃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工丘损, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留普办,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓徘钥,卻偏偏與公主長得像衔蹲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子呈础,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容