偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

系統(tǒng)成功率99.99%+,美團(tuán)CI/CD流水線引擎演進(jìn)實(shí)踐

原創(chuàng) 精選
開發(fā) 新聞
本文主要介紹美團(tuán)在自研引擎建設(shè)層面遇到的挑戰(zhàn)以及解決方案,希望對(duì)大家能夠有所幫助或啟發(fā)。

作者:耿杰 春暉 志遠(yuǎn)

經(jīng)過近3年的建設(shè)打磨,美團(tuán)流水線引擎完成了服務(wù)端的基建統(tǒng)一,每日支撐近十萬次的流水線執(zhí)行量,系統(tǒng)成功率保持在99.99%以上。

一、背景

持續(xù)交付這個(gè)概念最早在2006年敏捷大會(huì)上被提出,經(jīng)過多年的發(fā)展,目前已成為很多技術(shù)團(tuán)隊(duì)提升研發(fā)效能的必經(jīng)之路。通過建設(shè)部署流水線,打通從代碼開發(fā)到功能交付的整個(gè)環(huán)節(jié),以自動(dòng)化的方式完成構(gòu)建、測試、集成、發(fā)布等一系列行為,最終實(shí)現(xiàn)向用戶持續(xù)高效地交付價(jià)值。

流水線引擎作為支撐部署流水線的底座,它的好壞直接影響著部署流水線建設(shè)的水平。業(yè)界通常的做法是通過Jenkins、GitlabCI等開源工具(或公有云產(chǎn)品)進(jìn)行搭建,這是一條能幫助業(yè)務(wù)快速落地持續(xù)交付的道路,美團(tuán)早期也是采用搭建Jenkins的方式來快速支撐業(yè)務(wù)。

但隨著越來越多業(yè)務(wù)開始做持續(xù)交付的建設(shè),這種“短平快”方式的弊端逐漸顯現(xiàn)。比如,工具建設(shè)沒有統(tǒng)一的標(biāo)準(zhǔn),各業(yè)務(wù)都需要去了解整個(gè)工具鏈的細(xì)節(jié),建設(shè)成本高、水平參差不齊,很少有業(yè)務(wù)能搭建完整的部署流水線。同時(shí),業(yè)務(wù)每天的構(gòu)建量都在快速增長,逐漸超過Jenkins等開源工具所能承受的極限,在交付高峰期任務(wù)嚴(yán)重排隊(duì)、服務(wù)不可用現(xiàn)象頻出,嚴(yán)重影響著業(yè)務(wù)交付的順暢度。

美團(tuán)在流水線引擎的建設(shè)層面大概經(jīng)歷了幾個(gè)階段。在2019年以前,主要圍繞Jenkins進(jìn)行優(yōu)化,2019年開始正式立項(xiàng)打造自研的流水線引擎,大致的歷程如下:

第一階段(2014-2015):搭建Jenkins統(tǒng)一集群,解決業(yè)務(wù)接入的通用問題(如單點(diǎn)登錄、代碼倉庫集成、消息通知、執(zhí)行機(jī)的動(dòng)態(tài)擴(kuò)縮等),降低業(yè)務(wù)的建設(shè)成本。

  • 第二階段(2016-2018):拆分多個(gè)Jenkins集群,解決業(yè)務(wù)增長導(dǎo)致單集群性能瓶頸。最多時(shí)有十幾個(gè)集群,這些集群通常是按業(yè)務(wù)線維度劃分,并由業(yè)務(wù)自行建設(shè)。但隨著時(shí)間的推移,集群的拆分管理難度越來越大,Jenkins安全隱患頻出,對(duì)平臺(tái)方造成了很大的運(yùn)維負(fù)擔(dān)。
  • 第三階段(2019-至今):為了徹底解決引擎單機(jī)瓶頸和工具重復(fù)建設(shè)問題,我們開始自研分布式流水線引擎(美團(tuán)內(nèi)部項(xiàng)目名稱為Pipeline),并逐步收斂各業(yè)務(wù)依賴的底層基建。

經(jīng)過3年左右的建設(shè)打磨,流水線引擎完成了服務(wù)端的基建統(tǒng)一,涵蓋到店、到家、大眾點(diǎn)評(píng)、美團(tuán)優(yōu)選、美團(tuán)平臺(tái)、自動(dòng)配送車、基礎(chǔ)研發(fā)平臺(tái)等幾乎所有的業(yè)務(wù),支持Java、C++、NodeJS、Golang等多種語言。在性能和穩(wěn)定性方面,引擎每日支撐近十萬次的流水線執(zhí)行量(作業(yè)調(diào)度峰值每小時(shí)達(dá)上萬次),系統(tǒng)成功率保持在99.99%以上(排除業(yè)務(wù)代碼自身原因和第三方工具的問題)。

下面我們主要介紹下我們?cè)谧匝幸娼ㄔO(shè)上遇到的挑戰(zhàn)以及對(duì)應(yīng)的解決方案。

二、問題及思路

1、業(yè)務(wù)介紹

1)什么是流水線

我們可以把流水線的執(zhí)行看作是對(duì)代碼一步步加工,最終交付到線上的過程。根據(jù)業(yè)務(wù)定義的順序關(guān)系,依次執(zhí)行相應(yīng)的加工或質(zhì)量校驗(yàn)行為(如構(gòu)建、代碼掃描、接口測試、部署工具等),整個(gè)執(zhí)行過程類似一個(gè)有向無環(huán)圖。

圖1 流水線概念

2)基本概念

  • 組件:出于代碼復(fù)用和業(yè)務(wù)共享的考慮,我們將某一工具的操作行為封裝成一個(gè)組件,表示對(duì)于一項(xiàng)具體的加工或校驗(yàn)行為。通過組件方式,業(yè)務(wù)可以便捷地使用已集成的質(zhì)量工具(如靜態(tài)代碼掃描、安全漏洞分析等),減少在同一工具上的重復(fù)開發(fā)成本;對(duì)于不滿足需求的場景,業(yè)務(wù)可以自定義一個(gè)新的組件。
  • 組件作業(yè):表示組件的一次運(yùn)行實(shí)例。
  • 資源:為組件作業(yè)分配的一個(gè)可執(zhí)行環(huán)境。
  • 流水線編排:表示流水線中不同組件執(zhí)行的先后順序。
  • 引擎:負(fù)責(zé)調(diào)度所有的組件作業(yè),為其分配相應(yīng)的執(zhí)行資源,保證流水線執(zhí)行按預(yù)期完成。

2、主要挑戰(zhàn)

1)調(diào)度效率瓶頸

對(duì)調(diào)度時(shí)間相對(duì)敏感,流水線大部分是短時(shí)作業(yè)(作業(yè)持續(xù)數(shù)十秒到分鐘不等),如果調(diào)度時(shí)間過長,業(yè)務(wù)能明顯感知到流水線執(zhí)行變慢了。我們需要保證作業(yè)調(diào)度時(shí)間在一個(gè)可控的范圍內(nèi),避免出現(xiàn)調(diào)度瓶頸。

  • 從業(yè)務(wù)場景考慮,調(diào)度邏輯存在一定的業(yè)務(wù)復(fù)雜性(如組件串并行判斷、優(yōu)先級(jí)搶占、降級(jí)跳過、復(fù)用上一次結(jié)果等),不僅僅是作業(yè)與資源的匹配計(jì)算,作業(yè)調(diào)度耗時(shí)存在一定的業(yè)務(wù)開銷。
  • 引擎支撐公司每天近十萬次的執(zhí)行量,峰值量情況下,并發(fā)調(diào)度的作業(yè)量大,常見的開源工具(Jenkins/GitLab CI/Tekton等)都是采用單體調(diào)度模式,作業(yè)是串行調(diào)度的,容易出現(xiàn)調(diào)度瓶頸。

2)資源分配問題

對(duì)于作業(yè)系統(tǒng)來說,作業(yè)數(shù)通常都是大于資源數(shù)的(真實(shí)部署情況,資源不是無限的),作業(yè)積壓是系統(tǒng)設(shè)計(jì)時(shí)必須考慮的問題。如何在有限的資源下,盡可能提高作業(yè)的吞吐能力,同時(shí)降低在資源不足情況時(shí)造成對(duì)核心業(yè)務(wù)場景的影響。

  • 如果只依靠動(dòng)態(tài)擴(kuò)容,容易出現(xiàn)資源不足時(shí)無法擴(kuò)容、作業(yè)排隊(duì)等待的情況。特別是對(duì)于依賴流水線做研發(fā)卡控的業(yè)務(wù),這會(huì)直接阻塞業(yè)務(wù)的上線流程。
  • 出于執(zhí)行耗時(shí)的考慮,大部分資源采用預(yù)部署的方式,縮短資源申請(qǐng)和應(yīng)用啟動(dòng)的準(zhǔn)備時(shí)間。而對(duì)于預(yù)部署的資源,如何進(jìn)行有效劃分,既保證每類資源都有一定配額,同時(shí)也避免出現(xiàn)部分資源利用率過低,影響作業(yè)整體的吞吐能力。
  • 不是所有工具的執(zhí)行資源都由引擎管理(如發(fā)布系統(tǒng),部署任務(wù)的資源管理是單獨(dú)的),在作業(yè)的資源分配上,還需要考慮不同的資源管理方式。

3)工具差異化問題

公司內(nèi)不同業(yè)務(wù)的差異化大,涉及的質(zhì)效類工具眾多,如何設(shè)計(jì)一個(gè)合適的插件化架構(gòu),滿足不同工具的接入需求。

  • 不同工具實(shí)現(xiàn)形式差異化大,有些工具有獨(dú)立的平臺(tái),可以通過接口方式進(jìn)行集成,有些僅僅是一段代碼片段,還需要提供相應(yīng)的運(yùn)行環(huán)境。面對(duì)不同的接入形態(tài),引擎如何屏蔽不同工具帶來的差異,使業(yè)務(wù)在編排流水線時(shí)不用關(guān)注到工具的實(shí)現(xiàn)細(xì)節(jié)。
  • 隨著業(yè)務(wù)場景的不斷豐富,組件執(zhí)行還會(huì)涉及人工交互(審批場景)、支持重試、異步處理、故障恢復(fù)等能力,這些能力的擴(kuò)展如何盡可能減少對(duì)系統(tǒng)的沖擊,降低實(shí)現(xiàn)的復(fù)雜度。

3、解決思路

1)拆分調(diào)度決策與資源分配,解決調(diào)度效率瓶頸

從上述分析,一個(gè)作業(yè)的實(shí)際調(diào)度耗時(shí) = 單個(gè)作業(yè)的調(diào)度耗時(shí) * 待調(diào)度的作業(yè)數(shù)。因?yàn)閱蝹€(gè)作業(yè)的調(diào)度耗時(shí)會(huì)受具體的業(yè)務(wù)邏輯影響,不確定性大,優(yōu)化空間有限。而串行調(diào)度問題相對(duì)明確,在作業(yè)調(diào)度時(shí)間和數(shù)量不可控的情況下,是一個(gè)合適的優(yōu)化方向。

關(guān)于串行調(diào)度,業(yè)界常見的做法是按照業(yè)務(wù)線維度拆分多個(gè)集群,分?jǐn)偪偟恼{(diào)度壓力。但這種方式存在的問題是資源分配不具備靈活性,很容易出現(xiàn)資源的分配不均,在整體資源不足時(shí),無法從全局上考慮高優(yōu)作業(yè)的資源分配。并且,多集群管理(新增集群/拆分現(xiàn)有集群)也是不小的運(yùn)維負(fù)擔(dān)。

進(jìn)一步分析,串行調(diào)度主要是為了避免資源競爭問題,獲得相對(duì)最優(yōu)的資源。這對(duì)于流水線場景(作業(yè)量大于資源量且都是短時(shí)作業(yè)),資源最優(yōu)解不是強(qiáng)訴求。并且,資源量的并發(fā)度相對(duì)作業(yè)量更可控,根據(jù)作業(yè)執(zhí)行快慢不同,我們通過主動(dòng)拉取作業(yè)的方式,控制拉取的數(shù)量和頻率,從而有效降低了資源競爭的情況。

最終,我們?cè)谠O(shè)計(jì)上采取了調(diào)度決策與資源分配分離的模式:

  • 調(diào)度決策:負(fù)責(zé)計(jì)算出可以調(diào)度的作業(yè),提交決策,等待合適的資源來執(zhí)行。該模塊具體水平擴(kuò)展,分擔(dān)調(diào)度決策的壓力。
  • 資源分配:負(fù)責(zé)維護(hù)作業(yè)與資源的關(guān)系,通過主動(dòng)拉取作業(yè)的方式,資源可以向任意的實(shí)例拉取作業(yè),取消了原先串行分配資源的單點(diǎn)限制。

在這種模式下,作業(yè)調(diào)度、資源分配都具備水平擴(kuò)展能力,擁有更高的性能和系統(tǒng)可用性。也利于作業(yè)調(diào)度的邏輯能夠獨(dú)立演進(jìn),便于開發(fā)、測試以及灰度上線。

2)引入資源池管理模式,實(shí)現(xiàn)資源的靈活分配

考慮到不是所有資源都由引擎管理,我們引入資源池的概念來屏蔽不同資源方式的差異,每個(gè)資源池代表一類資源的集合,不同資源池的資源管理方式可以是多樣化的。通過該方式,我們將資源分配的問題簡化為作業(yè)與資源池的匹配問題,根據(jù)作業(yè)的實(shí)際情況,合理設(shè)置不同的資源池大小,并配合監(jiān)控手段對(duì)資源池進(jìn)行動(dòng)態(tài)調(diào)整。

在具體措施上,我們選擇“標(biāo)簽”的方式建立作業(yè)與資源池的匹配關(guān)系,通過從作業(yè)與資源兩個(gè)維度來滿足上述條件。

  • 在作業(yè)端,作業(yè)基于標(biāo)簽屬性拆分到不同的作業(yè)隊(duì)列,并引入優(yōu)先級(jí)概念,保證每個(gè)隊(duì)列中作業(yè)按優(yōu)先級(jí)高低被拉取到,避免在積壓時(shí),高優(yōu)作業(yè)排在后面無法被及時(shí)處理,阻塞業(yè)務(wù)研發(fā)流程。
  • 在資源端,結(jié)合資源的實(shí)際場景,提供三種不同的資源池管理方式,以解決不同資源類型的配額和利用率問題。

a. 預(yù)置的公共資源,這部分資源會(huì)提前在資源池上擴(kuò)容出來,主要應(yīng)對(duì)業(yè)務(wù)高頻使用的且對(duì)時(shí)間敏感的組件作業(yè)。在資源配額和利用率上,根據(jù)資源池的歷史情況和實(shí)時(shí)監(jiān)控,動(dòng)態(tài)調(diào)整不同資源池的大小。

b. 按需使用的資源,主要針對(duì)公共資源環(huán)境不滿足的情況,業(yè)務(wù)需要自定義資源環(huán)境,考慮到這部分作業(yè)的體量不大,直接采用實(shí)時(shí)擴(kuò)容的方式,相比預(yù)置資源的方式,可以獲得更好的資源利用率。

c. 外部平臺(tái)的資源,這些資源的管理平臺(tái)方比我們更有經(jīng)驗(yàn),平臺(tái)方通過控制向引擎拉取作業(yè)的頻率和數(shù)量,自行管理作業(yè)的吞吐情況。

3)引入組件的分層設(shè)計(jì),滿足工具差異化需求

為了保持工具接入的自由度,引擎提供了作業(yè)維度最基本的操作接口(拉取作業(yè)、查詢作業(yè)狀態(tài)、上報(bào)作業(yè)結(jié)果),不同工具可以根據(jù)作業(yè)接口形式實(shí)現(xiàn)定制化的組件開發(fā)。

組件開發(fā)主要涉及①實(shí)現(xiàn)業(yè)務(wù)邏輯和②確定交付方式兩部分工作,而與引擎的系統(tǒng)交互相對(duì)是標(biāo)準(zhǔn)的。我們根據(jù)組件執(zhí)行過程進(jìn)行分層設(shè)計(jì),拆分出業(yè)務(wù)邏輯、系統(tǒng)交互與執(zhí)行資源三層。在向引擎屏蔽工具實(shí)現(xiàn)細(xì)節(jié)的同時(shí),可以更好地滿足多樣化的接入場景。

  • 系統(tǒng)交互層,該層相對(duì)組件開發(fā)者是透明的,根據(jù)引擎提供的接口制定統(tǒng)一的流程交互標(biāo)準(zhǔn),以向引擎屏蔽不同組件的實(shí)現(xiàn)差異。
  • 執(zhí)行資源層,主要解決工具運(yùn)行方式的差異化,通過支持多種組件交付形式(如鏡像、插件安裝、獨(dú)立服務(wù))滿足工具與引擎的不同集成方式。
  • 業(yè)務(wù)邏輯層,針對(duì)業(yè)務(wù)不同的開發(fā)場景,采用多種適配器的選擇,來滿足業(yè)務(wù)不同的開發(fā)訴求。

三、整體架構(gòu)

圖片

圖2 流水線架構(gòu)

  • 觸發(fā)器:作為流水線的觸發(fā)入口,管理多種觸發(fā)源及觸發(fā)規(guī)則(Pull Request、Git Push、API 觸發(fā)、定時(shí)觸發(fā)等)。
  • 任務(wù)中心:管理流水線構(gòu)建過程中的運(yùn)行實(shí)例,提供流水線運(yùn)行、中止、重試、組件作業(yè)結(jié)果上報(bào)等操作。
  • 決策者:對(duì)所有等待調(diào)度的作業(yè)進(jìn)行決策,并將決策結(jié)果同步給任務(wù)中心,由任務(wù)中心進(jìn)行作業(yè)狀態(tài)的變更。
  • Worker:負(fù)責(zé)向任務(wù)中心拉取可執(zhí)行的作業(yè),并為作業(yè)分配具體的執(zhí)行資源。
  • 組件SDK:作為執(zhí)行組件業(yè)務(wù)邏輯的殼,負(fù)責(zé)真正調(diào)起組件,完成組件初始化與狀態(tài)同步的系統(tǒng)交互。

四、核心設(shè)計(jì)點(diǎn)

1、作業(yè)調(diào)度設(shè)計(jì)

1)調(diào)度過程

下面,我們以一個(gè)簡單的流水線調(diào)度示例(源碼檢出 - [并行:代碼掃描,構(gòu)建] - 部署),來介紹調(diào)度設(shè)計(jì)中各模塊的協(xié)作過程。

圖片

圖3 調(diào)度過程

大致邏輯如下:

①當(dāng)觸發(fā)流水線構(gòu)建后,系統(tǒng)會(huì)在任務(wù)中心創(chuàng)建該編排所要執(zhí)行的所有組件作業(yè)。并且將作業(yè)狀態(tài)的變化以事件方式通知決策者進(jìn)行決策。

②決策者接收決策事件,根據(jù)決策算法計(jì)算出可被調(diào)度的作業(yè),向任務(wù)中心提交作業(yè)的狀態(tài)變更請(qǐng)求。

③任務(wù)中心接收決策請(qǐng)求,完成作業(yè)狀態(tài)變更(作業(yè)狀態(tài)變更為已決策),同時(shí)加入相應(yīng)的等待隊(duì)列。

④Worker 通過長輪詢方式拉取到和自己匹配的等待隊(duì)列的作業(yè),開始執(zhí)行作業(yè),執(zhí)行完成后將結(jié)果上報(bào)給任務(wù)中心。

⑤任務(wù)中心根據(jù)Worker上報(bào)的作業(yè)執(zhí)行結(jié)果變更作業(yè)狀態(tài),同時(shí)向決策者發(fā)起下一輪決策。

⑥以此反復(fù),直至流水線下所有作業(yè)都已執(zhí)行完成或出現(xiàn)作業(yè)失敗的情況,對(duì)流水線進(jìn)行最終決策,結(jié)束本次執(zhí)行。

整個(gè)過程中,任務(wù)中心作為一個(gè)分布式存儲(chǔ)服務(wù),統(tǒng)一維護(hù)流水線和作業(yè)的狀態(tài)信息,以API方式與其他模塊進(jìn)行交互。而決策者和Worker通過監(jiān)聽作業(yè)狀態(tài)的變化執(zhí)行相應(yīng)的邏輯。

2)作業(yè)狀態(tài)流轉(zhuǎn)

下面是一個(gè)作業(yè)完整的狀態(tài)機(jī),我們通過作業(yè)決策、拉取、ACK以及結(jié)果上報(bào)一系列事件,最終完成作業(yè)從初始狀態(tài)向完結(jié)狀態(tài)的流轉(zhuǎn)過程。

狀態(tài)機(jī)在接收某種狀態(tài)轉(zhuǎn)移的事件(Event)后,將當(dāng)前狀態(tài)轉(zhuǎn)移至下一個(gè)狀態(tài)(Transition),并執(zhí)行相應(yīng)的轉(zhuǎn)移動(dòng)作(Action)。

圖片

圖4 狀態(tài)機(jī)

在實(shí)際場景中,由于調(diào)度過程涉及鏈路長、各環(huán)節(jié)穩(wěn)定性無法完全保證,容易產(chǎn)生因異常情況導(dǎo)致狀態(tài)不流轉(zhuǎn)的情況。為此,在設(shè)計(jì)上利用數(shù)據(jù)庫保證狀態(tài)變更的正確性,同時(shí)為非完結(jié)狀態(tài)作業(yè)設(shè)立相應(yīng)的補(bǔ)償機(jī)制,確保任一環(huán)節(jié)異常后作業(yè)可以恢復(fù)正確流轉(zhuǎn)。

我們重點(diǎn)從作業(yè)決策和作業(yè)拉取這兩個(gè)關(guān)鍵過程來看狀態(tài)流轉(zhuǎn)過程可能出現(xiàn)的問題,以及在設(shè)計(jì)上是如何解決的。

①作業(yè)決策過程:任務(wù)中心接收調(diào)度作業(yè)的決策,將可調(diào)度的作業(yè)從unstart變?yōu)閜ending狀態(tài),同時(shí)將作業(yè)加入等待隊(duì)列,等待被拉取。

圖片

圖5 狀態(tài)機(jī)-決策

  • 未收到?jīng)Q策事件:由于決策者服務(wù)自身的問題或網(wǎng)絡(luò)原因,導(dǎo)致決策事件的請(qǐng)求失敗,作業(yè)長時(shí)間處于未調(diào)度狀態(tài)。

解決方案:引入定時(shí)監(jiān)測的機(jī)制,對(duì)于無過程狀態(tài)作業(yè)且處于未完結(jié)狀態(tài)的流水線進(jìn)行重新決策,避免決策服務(wù)短時(shí)間異常導(dǎo)致決策失敗。

  • 重復(fù)決策:由于網(wǎng)絡(luò)延遲、消息重試現(xiàn)象可能出現(xiàn)多個(gè)決策者同時(shí)決策同一個(gè)作業(yè),產(chǎn)生作業(yè)轉(zhuǎn)移的并發(fā)問題。

解決方案:增加pending的狀態(tài)表示作業(yè)已被決策到,并通過數(shù)據(jù)庫樂觀鎖機(jī)制進(jìn)行狀態(tài)變更,保證僅有一個(gè)決策會(huì)真正生效。

  • 狀態(tài)變更過程異常:由于存在異構(gòu)數(shù)據(jù)庫,狀態(tài)變更和加入隊(duì)列可能存在數(shù)據(jù)不一致,導(dǎo)致作業(yè)無法被正常調(diào)度。

解決方案:采用最終一致性的方案,允許調(diào)度的短暫延遲。采用先變更數(shù)據(jù)庫,再加入隊(duì)列的操作順序。利用補(bǔ)償機(jī)制,定時(shí)監(jiān)測隊(duì)列隊(duì)首的作業(yè)信息,若pending狀態(tài)下的作業(yè)有早于隊(duì)首作業(yè)的,進(jìn)行重新入隊(duì)操作。

②作業(yè)拉取過程:任務(wù)中心根據(jù)Worker拉取作業(yè)的事件請(qǐng)求,從等待隊(duì)列中獲取待調(diào)度作業(yè),將作業(yè)的狀態(tài)從pending變更為scheduled,并返回給Worker。

圖片

圖6 狀態(tài)機(jī)-ACK

  • 作業(yè)丟失問題:這里存在兩種情況,①作業(yè)從隊(duì)列中移除,但在狀態(tài)將要變更時(shí)異常了;②作業(yè)從隊(duì)列中移除,也正確變更了狀態(tài)。但由于poll請(qǐng)求連接超時(shí),未正常返回給Worker。

解決方案:前者通過作業(yè)決策環(huán)節(jié)中對(duì)pending狀態(tài)的作業(yè)補(bǔ)償機(jī)制,重新加入隊(duì)列;后者對(duì)于狀態(tài)已變更的情況,已調(diào)度的作業(yè)增加ACK機(jī)制,若超時(shí)未確認(rèn),狀態(tài)會(huì)流轉(zhuǎn)回pending狀態(tài),等待被重新拉取。

  • 作業(yè)被多個(gè)Worker拉?。篧orker在接收到作業(yè)后,遇到長時(shí)間的GC,導(dǎo)致狀態(tài)流轉(zhuǎn)回pending狀態(tài),在Worker恢復(fù)后,可能出現(xiàn)作業(yè)已分配到另一個(gè)Worker上。

解決方案:通過數(shù)據(jù)庫樂觀鎖機(jī)制保證僅有一個(gè)Worker更新成功,并記錄作業(yè)與Worker的關(guān)系,便于對(duì)作業(yè)進(jìn)行中止以及Worker故障后的恢復(fù)操作。

3)決策過程

決策過程是從所有未啟動(dòng)的作業(yè)中篩選出可以被調(diào)度的作業(yè),通過一定的順序?qū)⑵涮峤唤o任務(wù)中心,等待被資源拉取的過程。整個(gè)篩選過程可以分為串并行順序、條件過濾、優(yōu)先級(jí)設(shè)置三部分。

圖片

圖7 決策過程

  • 串并行順序:相對(duì)于DAG中復(fù)雜的尋路場景,流水線場景比較明確,是將代碼逐步加工驗(yàn)證,通過開發(fā)、測試、集成、上線等一系列階段的過程。階段間是嚴(yán)格串行的,階段內(nèi)出于執(zhí)行效率的考慮,會(huì)存在串并行執(zhí)行的情況。這里通過模型設(shè)計(jì),將DAG的調(diào)度問題轉(zhuǎn)變成作業(yè)的先后次序問題,引入run order概念,為每個(gè)組件作業(yè)設(shè)置具體的執(zhí)行次序,根據(jù)當(dāng)前已執(zhí)行作業(yè)的次序,快速篩選出下一批次序僅大于當(dāng)前的作業(yè),若并行執(zhí)行,僅需將作業(yè)的次序設(shè)置成相同即可。

圖片

圖8 串并行決策

  • 條件過濾:隨著業(yè)務(wù)場景擴(kuò)展,不是所有的作業(yè)都需要調(diào)度資源,進(jìn)行真正的執(zhí)行。如某類耗時(shí)的組件,在代碼和組件參數(shù)都不變的情況下,可以直接復(fù)用上一次的執(zhí)行結(jié)果,或者在系統(tǒng)層面針對(duì)某類工具異常時(shí)進(jìn)行組件跳過的降級(jí)操作。針對(duì)這類情況,在作業(yè)真正提交給任務(wù)中心之前,會(huì)增加一層條件判斷(條件分為全局設(shè)置的系統(tǒng)條件以及用戶條件),這些條件以責(zé)任鏈形式進(jìn)行依次匹配過濾,根據(jù)匹配到的條件單獨(dú)向任務(wù)中心提交決策。
  • 優(yōu)先級(jí)設(shè)置:從系統(tǒng)全局考慮,在作業(yè)出現(xiàn)積壓時(shí),業(yè)務(wù)更關(guān)心核心場景下整條流水線是否能盡早執(zhí)行完成,而不是單個(gè)作業(yè)的排隊(duì)情況。所以,在優(yōu)先級(jí)設(shè)置上除了基于時(shí)間戳的相對(duì)公平策略外,引入流水線類型的權(quán)重值(如發(fā)布流水線>自測流水線;人工觸發(fā)>定時(shí)執(zhí)行),保證核心場景流水線相關(guān)作業(yè)能夠盡早被調(diào)度到。

2、資源池劃分設(shè)計(jì)

1)整體方案

我們采用多隊(duì)列的設(shè)計(jì),結(jié)合標(biāo)簽建立作業(yè)隊(duì)列與資源池的匹配關(guān)系,以保障不同隊(duì)列資源的有效劃分,在出現(xiàn)隊(duì)列積壓、資源池故障、無可擴(kuò)資源等情況時(shí),最大限度地降低影響范圍,避免所有作業(yè)全局排隊(duì)等待的現(xiàn)象。

圖片

圖9 資源池架構(gòu)

2)模型關(guān)系

圖片

圖10 資源池模型對(duì)象

①作業(yè)隊(duì)列與標(biāo)簽的關(guān)系:隊(duì)列與標(biāo)簽采用1對(duì)1的關(guān)系,降低業(yè)務(wù)理解和運(yùn)維成本。

  • 當(dāng)隊(duì)列積壓時(shí),能快速定位到某個(gè)標(biāo)簽沒資源了。
  • 標(biāo)簽資源不足時(shí),也能快速判斷影響的具體隊(duì)列情況。

②標(biāo)簽與資源池的關(guān)系:標(biāo)簽和資源池采用多對(duì)多的關(guān)系,主要從資源整體利用率和對(duì)核心隊(duì)列的資源可用性保障考慮。

  • 對(duì)于一些作業(yè)量較少的隊(duì)列,單獨(dú)分配一個(gè)資源池會(huì)造成大部分時(shí)間資源是空閑狀態(tài),資源利用率低。我們通過給資源池打多標(biāo)簽的方式,既保證了隊(duì)列有一定的資源配額,同時(shí)也能處理其他標(biāo)簽的作業(yè),提高資源的利用率。
  • 對(duì)于核心場景的隊(duì)列,通常標(biāo)簽資源會(huì)分配到多個(gè)資源池上,保證資源的一定冗余,同時(shí)也降低單個(gè)資源池整體故障帶來的影響。

3)標(biāo)簽設(shè)計(jì)

標(biāo)簽的目的是建立資源(池)與作業(yè)(隊(duì)列)的匹配關(guān)系。在設(shè)計(jì)上,為便于標(biāo)簽管理和后期維護(hù),我們采用二維標(biāo)簽的形式,通過組件和流水線兩個(gè)維度,共同決定一個(gè)作業(yè)所屬標(biāo)簽及對(duì)應(yīng)的資源。

  • 第一維度:組件維度,對(duì)資源做通用劃分。結(jié)合組件的業(yè)務(wù)覆蓋情況、作業(yè)執(zhí)行量、對(duì)機(jī)器和環(huán)境的特殊要求(如SSD、Dev環(huán)境等),對(duì)需要獨(dú)立資源的組件進(jìn)行打標(biāo),劃分出不同的公共資源池(每個(gè)公共資源池執(zhí)行一類或多類組件作業(yè)),在引擎層面統(tǒng)一分配,保證所有作業(yè)都有可正常運(yùn)行。
  • 第二維度:流水線維度,根據(jù)業(yè)務(wù)場景進(jìn)行劃分。結(jié)合業(yè)務(wù)對(duì)資源隔離/作業(yè)積壓敏感度的訴求,按需進(jìn)行劃分。有些希望資源完全獨(dú)立的業(yè)務(wù),會(huì)從所有的公共資源池進(jìn)行切分;有些僅對(duì)部分核心場景下的資源需要保障,根據(jù)鏈路上涉及的組件,選擇性地從部分公共資源池進(jìn)行劃分,實(shí)現(xiàn)業(yè)務(wù)隔離和資源利用率的平衡。

注:每個(gè)維度都會(huì)設(shè)一個(gè)other的默認(rèn)值用來兜底,用于處理無資源劃分需求的場景。

圖片

圖11 標(biāo)簽設(shè)計(jì)

4)隊(duì)列拆分設(shè)計(jì)

根據(jù)作業(yè)所屬標(biāo)簽不同拆分出多個(gè)隊(duì)列,保證每個(gè)隊(duì)列的獨(dú)立性,降低作業(yè)積壓的影響范圍。整個(gè)拆分過程可以分為入隊(duì)和出隊(duì)兩部分:

  • 入隊(duì)過程:通過計(jì)算作業(yè)在組件和流水線兩個(gè)維度的屬性值,來確定作業(yè)對(duì)應(yīng)的標(biāo)簽。結(jié)合模型關(guān)系中標(biāo)簽與隊(duì)列(1對(duì)1)的關(guān)系,為每個(gè)標(biāo)簽按需創(chuàng)建一個(gè)隊(duì)列,存儲(chǔ)該標(biāo)簽作業(yè),不同隊(duì)列間作業(yè)做排他處理,簡化出隊(duì)的實(shí)現(xiàn)復(fù)雜度。
  • 出隊(duì)過程:隊(duì)列拆分后,因?yàn)闃?biāo)簽和資源池(多對(duì)多)的關(guān)系,資源池的一次作業(yè)拉取請(qǐng)求往往會(huì)涉及多個(gè)隊(duì)列。出于拉取效率的考慮,采用輪詢的方式依次對(duì)單隊(duì)列進(jìn)行出隊(duì)操作,直到達(dá)到該次請(qǐng)求的作業(yè)數(shù)上限或所有可選隊(duì)列為空時(shí)返回結(jié)果。該方式可以避免同時(shí)對(duì)多個(gè)隊(duì)列加鎖,并且在前置環(huán)節(jié)會(huì)對(duì)多標(biāo)簽進(jìn)行隨機(jī)排序,降低多個(gè)請(qǐng)求同時(shí)操作一個(gè)隊(duì)列的競爭概率。

圖片

圖12 隊(duì)列拉取設(shè)計(jì)

3、組件分層設(shè)計(jì)

1)分層架構(gòu)

圖片

圖13 組件架構(gòu)設(shè)計(jì)

  • 業(yè)務(wù)層:引入適配層,滿足組件開發(fā)中多樣化的需求場景,同時(shí)避免上層差異污染到下層。
  • 系統(tǒng)交互層:設(shè)立統(tǒng)一的流程標(biāo)準(zhǔn),保證引擎和組件交互過程的一致性,便于統(tǒng)一處理非功能性的系統(tǒng)優(yōu)化。
  • 執(zhí)行資源層:提供多種資源策略,向上層屏蔽不同資源類型的差異。

2)標(biāo)準(zhǔn)的交互流程設(shè)計(jì)

在系統(tǒng)交互層,組件與引擎交互的過程中,有兩個(gè)環(huán)節(jié)是確定的,①組件作業(yè)的狀態(tài)機(jī)流轉(zhuǎn),這涉及到組件執(zhí)行的整個(gè)生命周期管理,若允許存在不同的狀態(tài)流轉(zhuǎn)關(guān)系,整個(gè)管理過程會(huì)十分混亂;②引擎對(duì)外提供的接口范圍,從服務(wù)間解耦的角度,對(duì)外提供的接口主要是組件作業(yè)維度的接口操作,不應(yīng)該耦合任何組件內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)。

結(jié)合作業(yè)狀態(tài)機(jī) + 引擎提供的接口,確定了組件執(zhí)行基本的系統(tǒng)交互流程。利用模版模式,抽象出init()、run()、queryResult()、uploadArtifacts() 等必要方法供業(yè)務(wù)實(shí)現(xiàn),整個(gè)交互流程則由系統(tǒng)統(tǒng)一處理,業(yè)務(wù)無需關(guān)心。

圖片

圖14 組件標(biāo)準(zhǔn)流程設(shè)計(jì)

3)擴(kuò)展基礎(chǔ)能力

組件執(zhí)行除了正常的執(zhí)行流程外,隨著業(yè)務(wù)場景的豐富,還會(huì)涉及組件中止、回調(diào)(人工審批場景)等操作,這些操作的引入勢必會(huì)改變?cè)鹊慕换チ鞒?。為了不增加額外的交互復(fù)雜度,在拉取作業(yè)環(huán)節(jié),增加作業(yè)的事件類型(運(yùn)行、中止、回調(diào)等事件),Worker根據(jù)拉取到的不同事件,執(zhí)行相應(yīng)的擴(kuò)展邏輯。同時(shí),引入新的擴(kuò)展也不會(huì)影響到已有的交互流程。

圖片

圖15 組件擴(kuò)展能力設(shè)計(jì)

基于上述擴(kuò)展,我們可能更好地將一些通用能力下沉到Daemon Thread層。如結(jié)果查詢流程,通過守護(hù)線程的方式,取消了原先同步等待的查詢限制,這對(duì)于需要異步化處理的場景(如組件作業(yè)邏輯已執(zhí)行完,僅在等待外部平臺(tái)接口返回結(jié)果)可以提前釋放資源,提高資源執(zhí)行的利用率。并且,當(dāng)執(zhí)行資源故障重啟后,結(jié)果查詢線程會(huì)自動(dòng)恢復(fù)待處理異步作業(yè)。這部分能力的支持在業(yè)務(wù)層是透明的,不改變整個(gè)交互流程。

4)引入適配器

業(yè)務(wù)雖可以通過必要方法完成自定義組件,但這些方法過于基礎(chǔ),業(yè)務(wù)在一些特定場景下實(shí)現(xiàn)成本較高。如對(duì)于組件支持Shell的腳本化調(diào)用,業(yè)務(wù)其實(shí)僅需提供可執(zhí)行的Shell即可,通用約定的方式,其他必要方法的實(shí)現(xiàn)都可以交由系統(tǒng)完成。

針對(duì)業(yè)務(wù)個(gè)性化的處理,采用適配器模式,通用引入不同Command(ShellCommand、xxCommand)來默認(rèn)實(shí)現(xiàn)特定場景下的必要方法,降低業(yè)務(wù)的開發(fā)成本。同時(shí),保持系統(tǒng)側(cè)流程的一致性,通過動(dòng)態(tài)注入Command的方式,防止對(duì)業(yè)務(wù)個(gè)性化處理的耦合。

圖片

圖16 組件適配器設(shè)計(jì)

5)效果

目前已支持Shell組件、服務(wù)組件、容器組件等多種接入方式,平臺(tái)上已提供數(shù)百個(gè)組件,組件開發(fā)方涉及數(shù)十個(gè)業(yè)務(wù)線。組件庫覆蓋源碼域、構(gòu)建域、測試域、部署域、人工審批域等多個(gè)環(huán)節(jié),打通了研發(fā)過程所涉及的各個(gè)基礎(chǔ)工具。

圖片

圖17 組件庫

五、后續(xù)規(guī)劃

  • 借助Serverless等云原生技術(shù),探索更輕量、高效的資源管理方案,提供更精細(xì)化的資源策略,從資源的彈性、啟動(dòng)加速、環(huán)境隔離三個(gè)方面為業(yè)務(wù)提供更優(yōu)的資源托管能力。
  • 面向組件開發(fā)者,提供從開發(fā)、上線到運(yùn)營的一站式開發(fā)管理平臺(tái),降低組件開發(fā)、運(yùn)營成本,使更多工具方、個(gè)人開發(fā)者能參與其中,共同打造豐富多樣的業(yè)務(wù)場景,形成良性的組件運(yùn)營生態(tài)。?
責(zé)任編輯:張燕妮 來源: 美團(tuán)技術(shù)團(tuán)隊(duì)
相關(guān)推薦

2019-11-07 09:00:39

Jenkins流水線開源

2023-08-18 10:24:52

GitLabCI 流水線

2024-01-07 12:47:35

Golang流水線設(shè)計(jì)模式

2022-07-18 06:05:28

Gitlab流水線

2023-09-27 08:24:49

2025-05-08 07:36:57

DevOpsSpringCI/CD

2023-11-08 00:25:14

CI云原生DevOps

2017-03-02 14:12:13

流水線代碼Clojure

2021-12-24 08:02:48

GitLabCI模板庫流水線優(yōu)化

2023-04-02 21:49:10

開源Tekton

2018-03-28 09:53:50

Android架構(gòu)演進(jìn)

2023-12-11 18:35:37

測試流水線自動(dòng)化

2021-04-29 08:55:54

GitLabDevOps項(xiàng)目

2017-02-28 15:40:30

Docker流水線Azure

2013-06-06 09:31:52

2021-11-08 07:41:16

Go流水線編程

2017-02-28 16:00:45

DevOpsMarkdownreST

2023-05-10 15:08:00

Pipeline設(shè)計(jì)模式

2020-10-25 11:28:12

開源端到端流水線

2012-10-23 14:27:55

無奈大裁員濾鏡拍照
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)