0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

微服務應用上/下線發(fā)布過程中存在的問題

jf_21561199 ? 來源:jf_21561199 ? 作者:jf_21561199 ? 2023-07-01 17:46 ? 次閱讀

一、微服務應用上/下線發(fā)布過程中存在的問題

在應用上下線發(fā)布過程中,如何做到流量的無損上/下線,是一個系統(tǒng)能保證 SLA 的關鍵。如果應用上下線不平滑,就會出現(xiàn)短時間的服務調(diào)用報錯,比如連接被拒絕、請求超時、沒有實例和請求異常等問題。

1.1 上線過程中的問題

在應用上線發(fā)布過程中,由于過早暴露服務,實例可能仍處在 JVMJIT 編譯或者使用的中間件還在加載,若此時大量流量進入,可能會瞬間壓垮新起的服務實例。我們在實際場景中,曾經(jīng)遇到 provider 服務啟動后,但是數(shù)據(jù)庫連接出現(xiàn)異常,未做好啟動前的資源準備,導致該 provider 服務在注冊中心暴露后 DB 異常還未修復,無法正常提供被 consumer 調(diào)用的能力,導致大量請求異常返回。如下圖日志所示,應用初始化時,DB 連接失?。ㄔ摲諏?DB 是弱依賴)。

wKgaomSf8nqACMj5AAJHs_VleJM024.png

1.2 下線過程中的問題

在應用下線過程中,服務消費者感知服務提供者下線有延遲,在一段時間內(nèi),被路由到已下線服務提供者實例的請求都拋連接被拒絕異常。其次服務實例在接收到 SIGKILL 信號時,會立即關閉,但是這時候可能在請求隊列中存在一部分請求還在處理,如果立即關閉這些請求都會損失掉。實際應用中,我們在環(huán)境上部署了 provider 的唯一一個實例,該服務被 consumer 調(diào)用,然后再執(zhí)行 kill-9強殺應用 provider 的唯一實例后,服務進程實際上已經(jīng)被終止,但是服務的注冊信息還會在注冊中心(該場景使用的是 ServiceComb)保留一段時間,未及時清除,如下圖所示。若此時消費者服務 consumer 調(diào)到該實例會報連接拒絕錯誤。因為消費者 consumer 服務還能發(fā)現(xiàn)該實例,獲取其 IP 和端口嘗試去調(diào)用,但是該 provider 服務實例其實已經(jīng)被銷毀了。

wKgZomSf8nqAfLoIAAFLJ3aK_cM985.png

二、如何處理應用上/下線問題

那么有哪些優(yōu)化措施,可以減少應用上/下線中流量的損失?

2.1 處理應用上線問題

應用上線發(fā)布主要問題是:其中一個原因是注冊太早,過早的暴露了服務;另一個原因是一些應用初始化緩慢,若遇到大量流量,應用容易宕機??梢圆扇∫韵聝?yōu)化措施:

1.延遲注冊:微服務應用可以采用延遲注冊的方式,即在應用啟動之后一定時間再進行注冊。這樣可以確保應用完全就緒后再注冊,避免了服務未就緒就被外部訪問的情況。

2.健康檢查:微服務應用可以實現(xiàn)健康檢查接口,通過該接口可以檢查服務是否就緒。注冊中心可以通過定期調(diào)用該接口來判斷服務是否可以對外提供服務,從而避免了服務未就緒就被外部訪問的情況。

3.預熱:對新實例進行預熱,而不是突然將所有流量轉(zhuǎn)移到新實例上,從而避免新實例遇到大量流量,應用容易宕機的情況。

4.啟動優(yōu)化:對于整個服務啟動的過程,可以進行一些優(yōu)化措施,比如減少不必要的依賴、調(diào)整啟動順序等,從而加快服務啟動速度。

2.2 應用合理的上線過程

合理的應用上線大致分為這樣一個過程:當應用啟動后,通過設置延遲注冊時間(服務對外暴露的時間)確保應用多久后可提供服務,其次可依賴平臺檢查服務的就緒狀態(tài)(比如 K8S 的就緒探針)確保服務對外提供服務為就緒狀態(tài),然后通過預熱對剛啟動應用進行保護,確保流量慢慢進入剛啟動的應用,最后流量逐漸增到正常情況。

wKgaomSf8nqAHGR9AAAYagZLjGE223.png

2.3 處理應用下線問題

應用下線過程最主要問題是:消費者應用無法及時感知到注冊中心列表的刷新,導致可能還有新流量訪問下線應用。可以采取以下優(yōu)化措施:

1.減少注冊中心緩存時間:將注冊中心中服務列表的緩存時間縮短,可以使消費者應用更快地獲取到服務列表的最新信息。這樣可以減少因服務列表緩存而導致的訪問下線應用的流量。

2.實時性優(yōu)化:在服務消費者和注冊中心之間使用長連接、實時通知等機制,從而能夠?qū)崟r獲取注冊中心中服務列表的變化。

3.實現(xiàn)熔斷機制:在消費者應用中實現(xiàn)熔斷機制,當某個服務實例出現(xiàn)故障或不可用時,可以快速切換到其他可用的服務實例。這樣可以避免將流量發(fā)送到已下線的應用程序上,并確保消費者應用的可用性。

2.4 應用合理的下線過程

合理的應用下線大致分為這樣一個過程:當應用接受到外部的關閉(停止服務)請求后,不能在接收新的業(yè)務請求,但是會存在一些正在處理的業(yè)務請求,需等這些請求處理完后再銷毀應用使用的資源,最后就可以通知主進程退出。

wKgZomSf8nuAQBb7AABBg6snEe8014.png

三、應用下線注意點

針對應用下線在虛機場景和容器場景需要關注一些注意點。

3.1 虛機場景

當我們要關閉虛擬機應用時,我們一般會使用 ps-ef|grepxxx 查找到進程 ID,然后再執(zhí)行 kill-9PID 操作。

kill命令使用科普

1.kill-9,系統(tǒng)會發(fā)出 SIGKILL(9)信號,由操作系統(tǒng)內(nèi)核完成殺進程操作,該信號不允許忽略和阻塞,應用程序會立即終止(強制殺死)。

2.kill-15,默認使用信號,系統(tǒng)向應用發(fā)送 SIGTERM(15)信號,給目標進程一個清理善后工作的機會是一種優(yōu)雅終止進程的方式,告訴進程需要停止運行并開始清理資源。

因為 kill-9PID 會強制殺死應用,以合理的應用下線流程看,應需處理完相關舊業(yè)務請求,清理相關資源后再退出進程,所以當要關閉虛擬機應用時,請執(zhí)行 killPID——以優(yōu)雅的方式停止運行。

3.2 容器場景

Kubernetes 目前是業(yè)界容器編排領域的事實標準,業(yè)界一般默認都是用 K8S 來管理容器。K8S 提供了 Pod 優(yōu)雅退出機制,允許 Pod 在退出前完成一些清理工作。preStop 會先執(zhí)行完,然后 K8S 才會給 Pod 發(fā)送 TERM 信號。在容器場景利用 K8S 提供的 preStop 機制,配合延遲下線 API 使用,這樣就能保證流量的無損下線。

...

spec:

containers:

-name:lifecycle-demo-container

image:nginx

lifecycle:

preStop:

exec:

command:["/bin/sh","-c","todoxxx;dosleep30;done"]

...

(1)為什么容器應用(K8S 環(huán)境)要配置 preStop?首先要介紹一下 Pod 的終止過程。

wKgaomSf8nyAJq5MAAGW1o6_gv0747.png

參考:https://kubernetes.renkeju.com/chapter_4/4.5.5.pod_termination_process.html

1.用戶發(fā)送刪除Pod對象的命令。

2.API服務器中的Pod對象會隨著時間的推移而更新,在寬限期內(nèi)(默認為 30 秒),Pod 被視為“dead”。

3.將Pod標記為“Terminating”狀態(tài)。

4.(與第 3 步同時運行)kubelet在監(jiān)控到Pod對象轉(zhuǎn)為“Terminating”狀態(tài)的同時啟動Pod關閉程序。

5.(與第 3 步同時運行)端點控制器監(jiān)控到Pod對象的關閉行為時將其從所有匹配到此端點的Service資源的端點列表中移除。

6.Pod對象中的容器進程收到TERM信號。

7.如果當前當前Pod對象定義了preStop鉤子處理器,則在其標記為“Terminating”后即會以同步的方式啟動執(zhí)行;如若寬限期結束后,preStop仍未執(zhí)行結束,則第 2 步會被重新執(zhí)行并額外獲取一個時長為 2 秒的小寬限期。

8.寬限期結束后,若存在任何一個仍在運行的進程,那么Pod對象即會收到SIGKILL信號。

9.kubelet請求APIServer將此Pod資源的寬限期設置為 0 從而完成刪除操作,它變得對用戶不在可見。

默認情況下,所有刪除操作的寬限期都是 30 秒,不過,kubectldelete命令可以使用“--grace-period=”選項自定義其時長,若使用 0 值則表示直接強制刪除指定的資源,不過,此時需要同時為命令使用“--force”選項。

從上述 Pod 終止過程的時序圖可知,關閉 Pod 流程(關注紅色框),給 Pod 內(nèi)的進程發(fā)送 TERM 信號(即 kill,kill-15),如果配置了 preStop 鉤子也會同時處理,最后寬限期結束后,若存在任何一個仍在運行的進程,那么 Pod 對象即會收到 SIGKILL(kill-9)信號。

(2)存在這樣一種情況 Pod 中的業(yè)務進程接受不到 SIGTERM 信號

存在這樣一種情況 Pod 中的業(yè)務進程接受不到 SIGTERM 信號(而且沒有配置 preStop 鉤子),等待一段時間業(yè)務進程直接被 SIGKILL 強制殺死了。

為什么業(yè)務進程接受不到 SIGTERM 信號?

通常都是因為容器啟動入口使用了shell,比如使用了類似/bin/sh-cmy-app或/docker-entrypoint.sh這樣的ENTRYPOINT或CMD,這就可能就會導致容器內(nèi)的業(yè)務進程收不到 SIGTERM 信號,原因是:

1.容器主進程是 shell,業(yè)務進程是在 shell 中啟動的,成為了 shell 進程的子進程。

2.shell進程默認不會處理SIGTERM信號,自己不會退出,也不會將信號傳遞給子進程,導致業(yè)務進程不會觸發(fā)停止邏輯。

3.當?shù)鹊終8S優(yōu)雅停止超時時間(terminationGracePeriodSeconds,默認 30s),發(fā)送 SIGKILL 強制殺死 shell 及其子進程。

(3)如何解決上述 Pod 中的業(yè)務進程接收不到 SIGTERM 信號問題

1.配置 preStop 鉤子(K8S 場景),處理退出前完成一些清理工作,比如使用無損上下線插件的應用服務需在停止前通知實例進行下線。

2.如果可以的話,盡量不使用shell啟動業(yè)務進程。

3.如果一定要通過shell啟動,比如在啟動前需要用shell進程一些判斷和處理,或者需要啟動多個進程,那么就需要在shell中傳遞下SIGTERM信號了。

所以容器應用(K8S 環(huán)境)要配置 preStop,在停止前通知實例進行下線,加了一層防護,保證 Pod 中的業(yè)務能優(yōu)雅的結束。

四、Sermant 如何解決應用上/下線問題

針對應用上下線發(fā)布過程中的問題,Sermant 插件提供預熱和延遲下線機制,為應用提供無損上下線的能力。預熱是無損上線的核心機制,延遲下線是無損下線的核心機制,而且為了無損上線,還做了延遲注冊機制。

4.1 上線問題的解決方式

wKgZomSf8nyASf3KAABD-U456ZY430.png

延遲注冊:若服務還未完全初始化就已經(jīng)注冊到注冊中心提供給消費者調(diào)用,很有可能因資源為加載完成導致請求報錯。可以通過設置延遲注冊,讓服務充分初始化后再注冊到注冊中心對外提供服務。

預熱:是基于客戶端實現(xiàn)的,當流量進入時,Sermant 會動態(tài)調(diào)整流量,根據(jù)服務的預熱配置,對流量進行動態(tài)分配。對于開啟服務預熱的實例,在剛啟動時,相對于其他已啟動的實例,分配的流量會更少,流量將以曲線方式隨時間推移增加直至與其他實例近乎持平。目的是采用少流量對服務實例進行初始化,防止服務崩潰。

4.2 下線問題的解決方式

wKgaomSf8n2AZEHfAAGyjm79Orc901.png

上圖描述了 Sermant 是如何解決服務下線問題的:

0.微服務應用 consumerA、providerA、consumerB、providerB 攜帶 Sermant 啟動,并將相關 ip:port 等信息注冊到注冊中心;

1.微服務應用 consumerA 可以正常調(diào)用 providerA 和 providerB;

2.若要重啟 providerA,providerA 會標記自身將下線(通知注冊中心將下線),并開始統(tǒng)計請求確保當前請求已全部處理完成;

3.providerA 會通知其上游應用其自身的下線信息;

4.consumerA 接受到 providerA 下線信息后,將其從緩存實例列表移除;

5.providerA 在處理完當前的所有請求后,即可重啟。

總的來說,Sermant 對于服務下線的機制概括為:

延遲下線:即對下線的實例提供保護,插件基于下線實時通知+刷新緩存的機制快速更新上游的實例緩存,同時基于流量統(tǒng)計的方式,確保即將下線的實例盡可能的將流量處理完成,最大程度避免流量丟失。提供了延遲下線 API,方便在 K8S 環(huán)境中配置 preStop。

流量統(tǒng)計:為確保當前請求已全部處理完成,在服務下線時,Sermant 會嘗試等待 30s(可配置),定時統(tǒng)計和判斷當前實例請求是否均處理完成,處理完成后最終下線。

五、總結

Sermant 插件為微服務應用提供無損上下線的能力,若要下線應用,針對虛擬場景,請使用 killPID;針對容器場景(K8S 環(huán)境),請配置 preStop 鉤子。

Sermant作為專注于服務治理領域的字節(jié)碼增強框架,致力于提供高性能、可擴展、易接入、功能豐富的服務治理體驗,并會在每個版本中做好性能、功能、體驗的看護。

編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 容器
    +關注

    關注

    0

    文章

    492

    瀏覽量

    22027
  • 華為云
    +關注

    關注

    3

    文章

    2391

    瀏覽量

    17247
收藏 人收藏

    評論

    相關推薦

    使用阿里云ACM簡化你的Spring Cloud微服務環(huán)境配置管理

    是只創(chuàng)建一個構建物,并將其配置單獨管理。從形式上來說,這針對的可能是每個環(huán)境一個屬性文件,或者是傳入到安裝過程中的一些參數(shù)。還有一個在應對大量微服務時比較流行的方法是,使用專用系統(tǒng)來提供配置,第11章會
    發(fā)表于 07-04 17:16

    微服務架構和CQRS架構基本概念介紹

    微服務架構現(xiàn)在很熱,到處可以看到各大互聯(lián)網(wǎng)公司的微服務實踐的分享總結。但是,我今天的分享和微服務沒有關系,希望可以帶給大家一些新的東西。如果一定要說微服務和CQRS架構的關系,那我覺得
    發(fā)表于 05-22 09:03

    微服務網(wǎng)關gateway的相關資料推薦

    采用微服務架構,顯示在產(chǎn)品頁上的數(shù)據(jù)會分布在不同的微服務上,比如:購物車服務——購物車的件數(shù)訂單服務——歷史訂單目錄
    發(fā)表于 12-23 08:19

    云芯一號ARM微服務器板卡的方法和過程介紹

    1、云芯一號統(tǒng)一固件和多分區(qū)鏡像文件的方法云芯一號是極術社區(qū)發(fā)布的一款ARM微型服務器板卡,有幸成為“云芯一號”ARM微服務器的第一批試用工程師。在收到“云芯一號”ARM微服務器板卡后
    發(fā)表于 06-16 16:02

    java微服務生態(tài)系統(tǒng)模型解讀

    微服務并不是孤立存在的,它們存在于一個環(huán)境里,微服務在這個環(huán)境里進行交互。把這種環(huán)境看成微服務生態(tài)系統(tǒng)并分層,有助于理解
    發(fā)表于 09-27 13:06 ?0次下載
    java<b class='flag-5'>微服務</b>生態(tài)系統(tǒng)模型解讀

    微服務與容器技術實踐

    基于微服務架構的技術實踐(點擊下載演講PPT) 普元信息主任架構師顧偉在演講,分享了他們對微服務架構的認識,包括微服務演進過程、常見認知誤
    發(fā)表于 10-10 10:23 ?1次下載
    <b class='flag-5'>微服務</b>與容器技術實踐

    微服務優(yōu)勢_微服務架構的好處與不足

    微服務是用一組小服務的方式來構建一個應用,服務獨立運行在不同的進程,服務之間通過輕量的通訊機制(如RESTful接口)來交互,并且
    發(fā)表于 02-23 11:24 ?4382次閱讀

    什么是微服務和容器?微服務和容器的作用是什么

    微服務是將應用程序拆分為多個服務的一種架構類型,這些服務具備構成整個應用程序的細粒度功能。每個微服務將具備針對您的應用程序的不同邏輯功能。與應用程序的所有組件和功能都在單個實例
    的頭像 發(fā)表于 01-13 10:54 ?3.2w次閱讀
    什么是<b class='flag-5'>微服務</b>和容器?<b class='flag-5'>微服務</b>和容器的作用是什么

    什么是微服務架構_微服務架構的優(yōu)缺點及應用

    什么是微服務架構 簡單地說,微服務是系統(tǒng)架構上的一種設計風格, 它的主旨是將一個原本獨立的系統(tǒng)拆分成多個小型服務,這些小型服務都在各自獨立的進程
    的頭像 發(fā)表于 06-02 10:03 ?1.7w次閱讀
    什么是<b class='flag-5'>微服務</b>架構_<b class='flag-5'>微服務</b>架構的優(yōu)缺點及應用

    微服務使用失敗的原因有什么

    在過去的幾年中,我已經(jīng)完成了對處于數(shù)字化轉(zhuǎn)型過程中的多個產(chǎn)品團隊的架構審查。 大多數(shù)團隊都在按照微服務架構構建產(chǎn)品。 他們有使用基于微服務的體系結構的所有正確意圖-更快的開發(fā),更好的可伸縮性,更小的獨立團隊,獨立的部署,使用正確
    的頭像 發(fā)表于 05-03 18:00 ?3480次閱讀

    微服務架構服務之間如何互相調(diào)用呢?

    微服務架構,需要調(diào)用很多服務才能完成一項功能。服務之間如何互相調(diào)用就變成微服務架構的一個關
    的頭像 發(fā)表于 01-31 09:46 ?2149次閱讀

    springcloud微服務架構

    Spring Cloud是一個開源的微服務架構框架,它提供了一系列工具和組件,用于構建和管理分布式系統(tǒng)微服務。它基于Spring框架,旨在通過簡化開發(fā)過程和降低系統(tǒng)復雜性來幫助開發(fā)
    的頭像 發(fā)表于 11-23 09:24 ?1166次閱讀

    docker微服務架構實戰(zhàn)

    的容器化技術,為微服務架構的實施提供了強大的支持。本文將介紹Docker微服務架構的實戰(zhàn)經(jīng)驗,包括Docker的概述、微服務架構的設計原則以及實際應用的具體實踐。 一、Docker概
    的頭像 發(fā)表于 11-23 09:26 ?616次閱讀

    設計微服務架構的原則

    微服務是一種軟件架構策略,有利于改善整體性能和可擴展性。你可能會想,我的團隊需不需要采用微服務,設計微服務架構有哪些原則?本文會給你一些靈感。文章速覽:微服務設計的要素
    的頭像 發(fā)表于 11-26 08:05 ?538次閱讀
    設計<b class='flag-5'>微服務</b>架構的原則

    微服務架構與容器云的關系與區(qū)別

    微服務架構與容器云密切相關又有所區(qū)別。微服務將大型應用拆分為小型、獨立的服務,而容器云基于容器技術,為微服務提供構建、發(fā)布和運行的平臺。區(qū)別
    的頭像 發(fā)表于 10-21 17:28 ?148次閱讀