43. 從零開始學(xué)springboot整合feign跨服務(wù)調(diào)用

介紹

微服務(wù)橫行的互聯(lián)網(wǎng)世界, 跨服務(wù)調(diào)用顯得很平凡, 我們除了采用傳統(tǒng)的http方式接口調(diào)用, 有沒有更為優(yōu)雅方便的方法呢?

答案是肯定的,feign就提供了輕便的方式!

如果你的服務(wù)都注冊了注冊中心,比如nacos, 那么調(diào)用會顯得很輕松, 只需一個(gè)注解, 帶上需要調(diào)用的服務(wù)名即可,feign + nacos會幫你做剩余的事.

如果沒有注冊中心, 也無需擔(dān)心, feign一樣可以以傳統(tǒng)的

ip:port

方式進(jìn)行調(diào)用~

下面,我們來實(shí)踐下吧

springboot整合feign

引入依賴, 這里注意, spring-cloud.version記得要和spring-boot版本匹配, 我這里spring-boot版本是2.1.3, 所以spring-cloud選擇Greenwich.SR2版本.

大致的版本對應(yīng)關(guān)系如下


image.png

更詳細(xì)的請去https://start.spring.io/actuator/info
查詢!

<properties>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>

<dependencyManagement>
        <dependencies>
            <!--SpringCloud依賴 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--openfeign跨服務(wù)調(diào)用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--openfeign底層使用ApacheHttpClient調(diào)用-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>
    </dependencies>

然后我們?nèi)ロ?xiàng)目的啟動類上加上注解
@EnableFeignClients

image.png

最后, 加上Feign的配置
application.properties

server.port=9999
#******************openfeign配置,參數(shù)采用的是默認(rèn)的配置看疙,可根據(jù)實(shí)際情況調(diào)整***********************
#啟用ApacheHttpClient豆拨。默認(rèn)就是true,使用HttpClientConnectionManager管理連接復(fù)用
feign.httpclient.enabled=true
#連接池的最大連接數(shù)能庆,默認(rèn)200
feign.httpclient.max-connections=200
#每個(gè)路由(服務(wù)器)分配的組最大連接數(shù)施禾,默認(rèn)50
feign.httpclient.max-connections-per-route=50
#連接最大存活時(shí)間,默認(rèn)900秒
feign.httpclient.time-to-live=900
#連接最大存活時(shí)間單位秒
feign.httpclient.time-to-live-unit=seconds
#FeignAcceptGzipEncodingInterceptor攔截器被激活搁胆,會在header中添加Accept-Encoding:gzip,deflate,表明服務(wù)端在返回值時(shí)可以使用如下兩個(gè)方式壓縮返回結(jié)果
feign.compression.response.enabled=true
#FeignContentGzipEncodingInterceptor攔截器被激活弥搞,會在header中添加Content-Encoding:gzip,deflate,表明body中的參數(shù)是使用這兩個(gè)方式的壓縮
feign.compression.request.enabled=true
#content-length大于2048就進(jìn)行請求參數(shù)的gzip壓縮
feign.compression.request.minRequestSize=2048


#開啟斷路器
feign.hystrix.enabled=true
#斷路器的隔離策略邮绿,默認(rèn)就是線程池,SEMAPHORE模式下攀例,就是主線程調(diào)用的遠(yuǎn)程的服務(wù)船逮,即同步的
hystrix.command.default.execution.isolation.strategy=THREAD
#斷路器超時(shí)設(shè)置
hystrix.command.default.execution.timeout.enabled=true
#總體請求在45秒還是無法得到響應(yīng),建議觸發(fā)熔斷(ribbon每個(gè)請求讀取15秒超時(shí)粤铭,兩個(gè)實(shí)例重試就是30秒傻唾,openfeign外層默認(rèn)會進(jìn)行一次調(diào)用,4次重試)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=45000
#斷路器的線程池存在一個(gè)問題承耿,在隊(duì)列滿了以后,不會再去創(chuàng)建新的線程直到maximumSize
#核心線程池大小
hystrix.threadpool.default.coreSize=10
#最大線程池大小
hystrix.threadpool.default.maximumSize=10
#超過這個(gè)空閑時(shí)間,多于coreSize數(shù)量的線程會被回收伪煤,1分鐘
hystrix.threadpool.default.keepAliveTimeMinutes=1
#隊(duì)列的大小加袋,默認(rèn)為-1,即沒有隊(duì)列
hystrix.threadpool.default.maxQueueSize=200
#隊(duì)列任務(wù)達(dá)到此閾值后抱既,就開始拒絕职烧;實(shí)際使用此參數(shù)進(jìn)行隊(duì)列是否滿的判斷
hystrix.threadpool.default.queueSizeRejectionThreshold=180



#負(fù)載均衡配置
#讀取超時(shí)15秒,與原RestTemplate保持一致
ribbon.ReadTimeout=15000
#連接超時(shí)15秒防泵,與原RestTemplate保持一致
ribbon.ConnectTimeout=15000
##每臺服務(wù)器最多重試次數(shù)蚀之,但是首次調(diào)用不包括在內(nèi)
ribbon.MaxAutoRetries=0
##最多重試多少臺服務(wù)器,與實(shí)際實(shí)例數(shù)保持一致(不包括首臺)
ribbon.MaxAutoRetriesNextServer=1
#是否所有操作都重試,
# false:get請求中捷泞,連接超時(shí)足删,讀取超時(shí)都會重試,其他請求(put,post)連接超時(shí)重試锁右,讀取超時(shí)不重試失受。
# true:get請求中,連接超時(shí)咏瑟,讀取超時(shí)都會重試拂到,其他請求(put,post)連接超時(shí)重試,讀取超時(shí)重試码泞。
#對于請求(put,post)要做好接口的冪等性
ribbon.OkToRetryOnAllOperations=true

spring-boot整合feign完成, 接下來我們編寫測試代碼

測試代碼

兩個(gè)服務(wù)

  • sb-alibaba-nacos (被調(diào)用方服務(wù), 127.0.0.1:8081), 提供 getInfoById接口

  • sb-feign (調(diào)用方服務(wù), 127.0.0.1:9999), 提供 getInfoById 測試接口

sb-alibaba-nacos提供的測試接口

    @GetMapping(value = "getInfoById")
    public String getInfoById(@RequestParam(value = "id") Long Id) {
        return "example-service return :" + Id;
    }

sb-feign相關(guān)代碼

我們新建個(gè)包 feign,用來放所有涉及跨服務(wù)調(diào)用的類


image.png

ExampleControllerFeignClient.java:

package com.mrcoder.sbfeign.feign;

import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "sb-alibaba-nacos", url = "http://127.0.0.1:8081/", fallbackFactory = ExampleControllerFeignClient.ExampleControllerFeignClientFallbackFactory.class)
public interface ExampleControllerFeignClient {

    @GetMapping(value = "getInfoById")
    String getInfoById(@RequestParam(value = "id") Long Id);

    /**
     * 服務(wù)降級內(nèi)部類
     */
    @Component
    class ExampleControllerFeignClientFallbackFactory implements FallbackFactory<ExampleControllerFeignClient> {

        private Logger logger = LoggerFactory.getLogger(ExampleControllerFeignClientFallbackFactory.class);

        @Override
        public ExampleControllerFeignClient create(Throwable cause) {
            return new ExampleControllerFeignClient() {
                @Override
                public String getInfoById(Long signingLogId) {
                    logger.error("跨服務(wù)調(diào)用失敗兄旬, 原因是:" + cause.getMessage());
                    return "失敗, 原因是:" + cause.getMessage();
                }
            };
        }
    }
}

關(guān)鍵代碼就是

@FeignClient(name = "sb-alibaba-nacos", url = "http://127.0.0.1:8081/", fallbackFactory = ExampleControllerFeignClient.ExampleControllerFeignClientFallbackFactory.class)
  • name 就是被調(diào)用方的服務(wù)名稱 (這里如果你沒有配置服務(wù)注冊中心的化,其實(shí)可以隨便寫)

  • url 就是被調(diào)用方的地址(如果配置了服務(wù)注冊中心, 可以不寫!, 不過兩個(gè)服務(wù)必須都注冊!,這樣才能找到!)

  • fallbackFactory 就是調(diào)用失敗時(shí)指定的處理類

最后, 我們寫個(gè)測試方法

package com.mrcoder.sbfeign.controller;

import com.mrcoder.sbfeign.feign.ExampleControllerFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@CrossOrigin
@RestController
public class TestController {

    @Autowired
    private ExampleControllerFeignClient exampleControllerFeignClient;

    @RequestMapping(value = "getInfoById", method = RequestMethod.GET)
    public String test(@RequestParam(value = "id") Long Id) {
        return exampleControllerFeignClient.getInfoById(Id);
    }
}

開啟兩個(gè)服務(wù)sb-alibaba-nacos, sb-feign

而后訪問sb-feign的測試方法

http://localhost:9999/getInfoById?id=22

出現(xiàn)

sb-alibaba-nacos return :22

跨服務(wù)調(diào)用成功~

項(xiàng)目地址

https://github.com/MrCoderStack/SpringBootDemo/tree/master/sb-feign

請關(guān)注我的訂閱號

訂閱號.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末余寥,一起剝皮案震驚了整個(gè)濱河市领铐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌劈狐,老刑警劉巖罐孝,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異肥缔,居然都是意外死亡莲兢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來改艇,“玉大人收班,你說我怎么就攤上這事≮诵郑” “怎么了摔桦?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長承疲。 經(jīng)常有香客問我邻耕,道長,這世上最難降的妖魔是什么燕鸽? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任兄世,我火速辦了婚禮,結(jié)果婚禮上啊研,老公的妹妹穿的比我還像新娘御滩。我一直安慰自己,他們只是感情好党远,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布削解。 她就那樣靜靜地躺著,像睡著了一般沟娱。 火紅的嫁衣襯著肌膚如雪氛驮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天济似,我揣著相機(jī)與錄音柳爽,去河邊找鬼。 笑死碱屁,一個(gè)胖子當(dāng)著我的面吹牛磷脯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娩脾,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赵誓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柿赊?” 一聲冷哼從身側(cè)響起俩功,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碰声,沒想到半個(gè)月后诡蜓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胰挑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年蔓罚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了椿肩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豺谈,死狀恐怖郑象,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情茬末,我是刑警寧澤厂榛,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站丽惭,受9級特大地震影響击奶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜责掏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一正歼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拷橘,春花似錦、人聲如沸喜爷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檩帐。三九已至术幔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間湃密,已是汗流浹背诅挑。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泛源,地道東北人拔妥。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像达箍,于是被迫代替她去往敵國和親没龙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354