SpringCloud微服務(wù)項(xiàng)目-無感知動態(tài)調(diào)整服務(wù)實(shí)例數(shù)量

隨著時間的流逝揖庄,java技術(shù)也在一次次的革新阿逃,現(xiàn)在大家基本都已經(jīng)在使用微服務(wù)開發(fā)了,spring-cloud就是java技術(shù)棧下最流行的微服務(wù)解決方案惹恃,在微服務(wù)領(lǐng)域,對服務(wù)數(shù)量的大小調(diào)整已成為一個非常常規(guī)的一個操作棺牧,那么在某個服務(wù)擴(kuò)容和削減服務(wù)數(shù)量的時候座舍,怎么能不影響線上的服務(wù)使用呢

一、關(guān)于擴(kuò)容

對于擴(kuò)容其實(shí)比較簡單陨帆,啟動新的服務(wù)實(shí)例,注冊到eurake上即可采蚀,其他調(diào)用服務(wù)的client端(包括zuul)每隔一段時間會從eureka server上拉取新的服務(wù)列表疲牵,當(dāng)啟動完成的服務(wù)實(shí)例注冊完成,各個client拉取到新的服務(wù)列表榆鼠,便可以正常訪問新增的服務(wù)實(shí)例了纲爸,全程無感知。

二妆够、關(guān)于下線削減服務(wù)數(shù)量

下線微服務(wù)實(shí)例识啦,使用kill -9直接強(qiáng)制殺掉進(jìn)程,肯定是不行的神妹,因?yàn)楦鱾€客戶端都還在調(diào)用該實(shí)例時颓哮,突然被殺掉進(jìn)程,肯定會報(bào)錯(這里我們先不考慮鸵荠,重試機(jī)制冕茅,這是另外的一個問題,粗暴的重試也會導(dǎo)致所有接口都做冪等性處理),如果調(diào)用springboot提供的優(yōu)雅關(guān)閉服務(wù)實(shí)例的方法姨伤,可能會導(dǎo)致關(guān)閉失敗哨坪,進(jìn)程無法關(guān)閉,而且關(guān)閉后乍楚,因?yàn)楦鱾€客戶端會緩存eureka上的服務(wù)列表(如果都使用默認(rèn)配置当编,緩存最長還會持續(xù)90秒的時間),這樣客戶端調(diào)用已經(jīng)下線的服務(wù)還是會報(bào)錯徒溪,那么下面進(jìn)入本文主題忿偷,介紹一種可以,完全不報(bào)錯词渤,無感知的下線服務(wù)實(shí)例方式:

eureka提供了一個方法eurekaClient.shutdown()牵舱,調(diào)用后會將該服務(wù)實(shí)例從eureka上摘除,不會再進(jìn)行注冊缺虐,但是服務(wù)實(shí)例并不會關(guān)閉芜壁,我們從eureka摘除服務(wù)以后,先不要?dú)⒌舴?wù)進(jìn)程高氮,這個時候因?yàn)楦鱾€客戶端的緩存的服務(wù)列表沒有更新慧妄,還會繼續(xù)調(diào)用該服務(wù),所以就要等待剪芍,等90秒后所有的客戶端都從eureka上拉去到最新的服務(wù)列表塞淹,不再調(diào)用該服務(wù)時,將進(jìn)程殺掉罪裹,這樣客戶端就不會感知到該服務(wù)的下線饱普。這種方式就是會耗費(fèi)一些等待緩存過期的時間,這個我們可以通過修改緩存時長状共,來縮短這個時間套耕,當(dāng)然也可以同時下線多個服務(wù)

三、代碼實(shí)例

/**
 * @author anjl
 * 2018-7-12
 */
@SuppressWarnings("unused,unchecked")
@Api(tags = "eureka操作接口")
@ApiResponses(value = {@ApiResponse(code = 400, response = GlobalExceptionHandler.class, message = "數(shù)據(jù)校驗(yàn)失敗"), @ApiResponse(code = 500, response = GlobalExceptionHandler.class, message = "內(nèi)部錯誤")})
@Slf4j
@RestController
@RequestMapping("/eureka")
public class EurekaClientController {

    @ApiOperation(value = "注銷eureka client", notes = "注銷eureka client", position = 10)
    @GetMapping("/shutdown")
    public BusinessResult shutdown() throws Exception {
        InstanceInfo info = eurekaClient.getApplicationInfoManager().getInfo();
        log.info("服務(wù)下線:instanceId = {}", info.getInstanceId());
        singleThreadPool.execute(this::shutdownClient);
        return BusinessResult.createSuccessInstance(null);
    }

    @ApiOperation(value = "用于檢測中間是否有停機(jī)", position = 10)
    @GetMapping("/test")
    public BusinessResult test() throws Exception {
        return BusinessResult.createSuccessInstance(null);
    }

    private void shutdownClient() {
        eurekaClient.shutdown();
        log.info("服務(wù)下線成功O考獭7肱邸!");
    }

    @Autowired
    private EurekaClient eurekaClient;

    private ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("app-eureka-shutdown-pool-%d").build();
    private ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1, 10L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

}

四碾牌、后續(xù)的一些說明

(1)從eureka server上也可以下線服務(wù)康愤,但是因?yàn)槲⒎?wù)實(shí)例的心跳并沒有停止,所以還是會重新注冊到eureka server上
(2)下線服務(wù)實(shí)例舶吗,采用異步處理主要是為了征冷,快速返回結(jié)果,在服務(wù)實(shí)例訪問量比較大的情況下裤翩,下線服務(wù)處理時間較長资盅,所以采用異步處理的方式调榄,先返回結(jié)果,同時異步去處理下線操作呵扛。
(3)如果我們項(xiàng)目資源比較緊張每庆,暫時只有一個服務(wù)實(shí)例,也可以通過這種方式實(shí)現(xiàn)不停機(jī)升級服務(wù)今穿,我們只需要在額外的端口啟動一個備份服務(wù)缤灵,然后通過上述方式將舊的服務(wù)下線,然后更新代碼后啟動蓝晒,再用上述方式下線備份服務(wù)即可(這樣的方案需要機(jī)器提供可以啟動一個備份服務(wù)的內(nèi)存)腮出。在啟動備份服務(wù)階段還可以檢查一些低級錯誤,比如配置文件錯誤或者編譯錯誤導(dǎo)致備份服務(wù)無法啟動成功芝薇,就可以不再向下執(zhí)行胚嘲。
(4)此方案好處:在聯(lián)調(diào)階段,不影響前端使用的情況下洛二,升級服務(wù)馋劈。
在測試階段不影響測試的情況下,修復(fù)bug晾嘶。
在線上環(huán)境不影響使用的情況下妓雾,服務(wù)升級。
總之大大提高了服務(wù)的可用性垒迂。
(ps:以前小編公司械姻,測試或者聯(lián)調(diào)階段,每次要更新代碼机断,都要在群里大喊”服務(wù)重啟“楷拳,重啟完,再大喊”完成“吏奸,喊的次數(shù)少了唯竹,更新不及時,喊的次數(shù)多了苦丁,又怕影響其他人工作,著實(shí)令小編為難N锉邸旺拉!
從此小編再也不用擔(dān)心重啟次數(shù)多的問題了,想怎么更新就怎么更新?昧住6旯贰)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仪媒,隨后出現(xiàn)的幾起案子沉桌,更是在濱河造成了極大的恐慌谢鹊,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件留凭,死亡現(xiàn)場離奇詭異佃扼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蔼夜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門兼耀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人求冷,你說我怎么就攤上這事瘤运。” “怎么了匠题?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵拯坟,是天一觀的道長。 經(jīng)常有香客問我韭山,道長郁季,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任掠哥,我火速辦了婚禮巩踏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘续搀。我一直安慰自己塞琼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布禁舷。 她就那樣靜靜地躺著彪杉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪牵咙。 梳的紋絲不亂的頭發(fā)上派近,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機(jī)與錄音洁桌,去河邊找鬼渴丸。 笑死,一個胖子當(dāng)著我的面吹牛另凌,可吹牛的內(nèi)容都是我干的谱轨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吠谢,長吁一口氣:“原來是場噩夢啊……” “哼土童!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起工坊,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤献汗,失蹤者是張志新(化名)和其女友劉穎敢订,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罢吃,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡楚午,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了刃麸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醒叁。...
    茶點(diǎn)故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泊业,靈堂內(nèi)的尸體忽然破棺而出把沼,到底是詐尸還是另有隱情,我是刑警寧澤吁伺,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布饮睬,位于F島的核電站,受9級特大地震影響篮奄,放射性物質(zhì)發(fā)生泄漏捆愁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一窟却、第九天 我趴在偏房一處隱蔽的房頂上張望昼丑。 院中可真熱鬧,春花似錦夸赫、人聲如沸菩帝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呼奢。三九已至,卻和暖如春切平,著一層夾襖步出監(jiān)牢的瞬間握础,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工悴品, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禀综,地道東北人。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓苔严,卻偏偏與公主長得像菇存,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邦蜜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評論 2 354