運維行業(yè)發(fā)展至今,從最初的人肉運維、腳本時代,到后期的平臺化階段、以及現(xiàn)在很火的AIOps的概念。都繞不過一個主題——資源管理。
無論是健全而人性化的發(fā)布體系、靈敏強大的監(jiān)控體系、還是穩(wěn)定高效的服務(wù)發(fā)現(xiàn),都需要我們有一種可以很靈活的管理資源的模型。
這個模型,應(yīng)該有如下兩個特點:
- 支持業(yè)務(wù)分級,可以與業(yè)務(wù)形態(tài)靈活對應(yīng)
- 篩選能力靈活,可以支持多個維度靈活精確的匹配與篩選
這就是服務(wù)樹概念的由來。接下來筆者會將我們在服務(wù)樹的建設(shè)過程中的一些思考和遇到的問題,分享給大家。
此篇文章專注介紹服務(wù)樹模型的設(shè)計與實現(xiàn)。用于資源管理的CMDB系統(tǒng),機器上下線、報修、借用歸還相關(guān)的資源全流程閉環(huán),此篇文章不做探討。
什么是服務(wù)樹
服務(wù)樹,一言以蔽之,是一個將業(yè)務(wù)映射成樹形結(jié)構(gòu),然后與資源對應(yīng)起來的模型。
通俗且狹義地講,服務(wù)樹維護著,哪個業(yè)務(wù)線下有哪幾臺機器、哪幾個VIP等資源。
與傳統(tǒng)意義的CMDB系統(tǒng)不同的是,服務(wù)樹專注于解決業(yè)務(wù)與資源的映射關(guān)系,而傳統(tǒng)的CMDB系統(tǒng)更多的關(guān)注于資源本身的屬性與狀態(tài)。
比如,一個公司下有N個事業(yè)群,每個事業(yè)群下有N個部門,每個部門內(nèi)有N個服務(wù),每個服務(wù)有N個模塊,每個模塊又有N個集群。邊說著,是不是你的腦中,就已經(jīng)出現(xiàn)了一棵樹?

接著我們可以想,每一個樹節(jié)點,都是一個單獨的空間,可以放一些機器、VIP之類的資源。當(dāng)我們把所有的資源,根據(jù)使用情況分別放置到樹的不同節(jié)點上時,這就是一棵服務(wù)樹啦。
樹的節(jié)點之間,天然就有繼承的關(guān)系,正好與業(yè)務(wù)的組織架構(gòu)對應(yīng)。
每一個樹的節(jié)點,我們稱之為 NS(NameSpace)。是不是有點類似編程語言的命名空間?
服務(wù)樹的由來
最初的時候,我們只有一個CMDB系統(tǒng),當(dāng)然這個系統(tǒng)可能只是一個excel表格。
后來我們要對機器進行批量操作,可能是某個服務(wù)的一批機器,可能是某個集群的一批機器,也有可能是某個產(chǎn)品線的所有機器,于是我們開始維護各種各樣的資源列表。
再后來,大家想,能不能搞個平臺,把所有的資源列表都管理起來。也就是,分組功能服務(wù)化。
然后就有了服務(wù)樹。

其實服務(wù)樹的發(fā)展過程,與運維系統(tǒng)平臺化的發(fā)展是基本同步的。因為越先進的運維系統(tǒng),就要求越強大越高效的資源管理系統(tǒng)。
服務(wù)樹的日常應(yīng)用
在我看來,服務(wù)樹的作用只有一個:靈活的篩選業(yè)務(wù)與資源的關(guān)聯(lián)關(guān)系。
在服務(wù)樹接管資源的管理之后,我們來看下如何利用服務(wù)樹更好的進行運維操作:
- 發(fā)布一個服務(wù)的時候,我可以指定將此服務(wù)發(fā)布至【服務(wù)樹某個節(jié)點】。
- 監(jiān)控一個進程是否存活,我可以指定,只采集【服務(wù)樹某個節(jié)點】的進程數(shù)據(jù)并報警。
- 一臺機器是混部的,很多業(yè)務(wù)線在共用。我可以查詢【該機器存在于哪幾個服務(wù)樹節(jié)點】,就能知道哪幾個業(yè)務(wù)線在使用。
- 我要給某個人授權(quán),可以不需要指定機器列表,可以只給他服務(wù)樹節(jié)點的權(quán)限即可。
上述這些情況,使用服務(wù)樹節(jié)點代替機器列表,帶來的好處有:
- 無需關(guān)心瑣碎的資源列表,所有操作對節(jié)點生效,簡潔明了,提高人員效率。
- 無需人工指定機器列表,由服務(wù)樹來補全,減少誤操作。
- 當(dāng)節(jié)點下機器發(fā)生變更,將直接在所有周邊系統(tǒng)生效,不需要人為干預(yù)。
服務(wù)樹節(jié)點規(guī)范的制定
服務(wù)樹的模型,說來并不算復(fù)雜。但是確實整個運維平臺最核心的地方。
當(dāng)我們做服務(wù)樹的時候,更多的,是做一個規(guī)范。
規(guī)范的制定,一定要非常慎重,因為規(guī)范一旦確定,模型就確定了,再改起來就會非常困難。
首先是層級的劃分,要根據(jù)公司的實際情況,與業(yè)務(wù)緊密關(guān)聯(lián)起來。最好有對公司體系架構(gòu)非常熟悉的人來幫忙review。
其次要考慮如何同時滿足各種靈活的篩選和調(diào)整??紤]當(dāng)前公司的各種系統(tǒng)對資源的檢索需求,設(shè)計模型是否可以滿足。
最后,服務(wù)樹模型的設(shè)計者一定要想明白這個模型,要在最大程度滿足業(yè)務(wù)需求的前提下,保留服務(wù)樹的靈活性。不要完全被業(yè)務(wù)所左右,要給我們的想象和未來留一點空間。
一般來講,服務(wù)樹規(guī)范分為命名規(guī)范和使用規(guī)范兩方面。
命名規(guī)范
命名規(guī)范主要是用來約束節(jié)點的命名。這些規(guī)則,是構(gòu)建一棵服務(wù)樹的具體規(guī)則。根據(jù)公司業(yè)務(wù)情況的不同所不同。
比如:
- 服務(wù)樹的節(jié)點必須有層級的概念,必須從上到下有【公司】【部門】【產(chǎn)品線】【service】不能缺省、其他的【servicegroup】可以缺省。
- 【servicegroup】層級可以嵌套和級聯(lián)。
- 【idc】【status】等在一臺機器上,必須唯一。
使用規(guī)范
使用規(guī)范用來約束服務(wù)樹的使用,同時約束周邊系統(tǒng)的行為。
可以與各個周邊系統(tǒng)的負(fù)責(zé)人來商量敲定。
比如:
- 監(jiān)控系統(tǒng)指標(biāo)只允許上報至葉子節(jié)點。
- 部署服務(wù)必須在【service】節(jié)點維度進行。
服務(wù)樹的實踐
這一部分,分享一個筆者老東家的一個服務(wù)樹的實踐,可謂是小巧靈活、彈性十足。
小巧,從邏輯上,核心的服務(wù)樹模型與機器全流程的運轉(zhuǎn),做了隔離。服務(wù)樹可以更好地專注于映射關(guān)系的處理。
靈活,這棵服務(wù)樹的層級之間的關(guān)系并不是固定的,而是由一個一個的標(biāo)簽組合而來。比如,我一臺機器,在【部門A-業(yè)務(wù)線B-集群C】,并不是做了這樣的綁定關(guān)系。而是分別給這臺機器打了【部門A】【業(yè)務(wù)線B】【集群C】三個關(guān)聯(lián)標(biāo)簽。
這樣,就可以隨意的組合各種標(biāo)簽,用來篩選資源,比如:【部門A-集群C】所有機器,可以篩選出【部門A】下所有業(yè)務(wù)線【集群C】的機器。
彈性,除了維護邏輯的關(guān)系之外,同時支持另一類標(biāo)簽,用來標(biāo)示資源的屬性。比如【機器狀態(tài)】【機器idc】等??梢灾С指嗑S度的篩選。
并且,允許用戶自定義服務(wù)樹視圖。比如,一個sys主機組的同學(xué),并不關(guān)心機器的所屬部門和業(yè)務(wù)情況,只關(guān)心壞掉的機器。那就可以將視圖設(shè)置為【公司X-狀態(tài)trouble】,這樣,看到的樹,只有兩級,并且可以完全的滿足他的篩選需求。
這棵樹的實現(xiàn)方式,比較簡單:一張資源表,一張節(jié)點表,一張關(guān)聯(lián)表。
節(jié)點表存的是排過序的tag組合串。平時的tag篩選,通過數(shù)據(jù)庫的like操作來實現(xiàn)。
資源相關(guān)的屬性標(biāo)簽,直接放在資源表里。
說來這個實現(xiàn)方式其實比較trick,只是打擦邊球?qū)崿F(xiàn)了服務(wù)樹的各種功能。
不過服務(wù)樹的數(shù)據(jù)體量一般不會太大,因此這個問題暴露的也不算太明顯。有查詢的瓶頸也可以通過加cache來解決。不過一旦機器量到達(dá)10W+,很可能就要從模型上來重構(gòu)了。
服務(wù)樹模型當(dāng)前的問題與瓶頸
問題一:與周邊的關(guān)聯(lián)
周邊系統(tǒng)要與服務(wù)樹打通,有兩種方式:
- 節(jié)點串關(guān)聯(lián):與周邊系統(tǒng)弱耦合。如果節(jié)點改名,需要有一個觸發(fā)式的通知機制,由周邊系統(tǒng)來訂閱。不利于解耦。
- ID關(guān)聯(lián):與周邊系統(tǒng)強耦合。使用服務(wù)樹的節(jié)點串唯一ID來做關(guān)聯(lián),改名可以不用通知。但是周邊系統(tǒng)每次都需要用ID向服務(wù)樹動態(tài)解析,一旦服務(wù)樹出現(xiàn)故障,很可能導(dǎo)致大量周邊系統(tǒng)不可用。
上述已知的兩種方式,都存在問題,目前也沒有很好的解決方式。筆者公司目前是使用的第一種方式,一旦服務(wù)樹出現(xiàn)問題,起碼可以保證周邊系統(tǒng)可用。
問題二:關(guān)聯(lián)了節(jié)點,卻失去了對資源本身的關(guān)注
筆者公司目前遇到了這樣的一種情況,機器A同時掛載到了兩個節(jié)點,監(jiān)控與服務(wù)樹是弱關(guān)聯(lián)。
因此監(jiān)控數(shù)據(jù)分為兩份,分別與兩個節(jié)點關(guān)聯(lián)。如果是業(yè)務(wù)數(shù)據(jù),那沒問題。但是由于我們監(jiān)控系統(tǒng)根據(jù)服務(wù)樹節(jié)點做了分片。基礎(chǔ)指標(biāo),也分了兩份,推往了不同的節(jié)點。
當(dāng)我配置一條大節(jié)點的策略:cpu.idle小于10的時候,報警出來。但是卻同時收到了兩條報警,因為節(jié)點不同,監(jiān)控系統(tǒng)認(rèn)為,這是兩條監(jiān)控數(shù)據(jù)。
那么問題來了,用戶視角:“為什么,同一臺機器,同一條監(jiān)控策略,你要給我發(fā)兩條報警??”
啞口無言。
雖然這個問題,通過報警的收斂可以解決。但是模型的不支持,卻讓我們耿耿于懷。
腦洞 & 思考
服務(wù)樹的本質(zhì)
服務(wù)樹,本質(zhì)上應(yīng)該只是一種視圖,而不應(yīng)該是一個實體。
關(guān)于資源本身的屬性,更多的應(yīng)該回歸到資源的本身。
周邊系統(tǒng)也是如此,應(yīng)當(dāng)對資源本身的屬性與正常的服務(wù)樹節(jié)點有所區(qū)分。
節(jié)點標(biāo)簽化
這篇文章介紹的一個實踐,仍然是有樹的實體的。在我的構(gòu)想里,整個系統(tǒng)應(yīng)該以資源為主體。
所有的服務(wù)樹信息,都以標(biāo)簽的形式,標(biāo)記在資源上。
只是標(biāo)簽需要分兩類:
- 一類標(biāo)簽,可以無限制標(biāo)記到資源。(比如:部門、產(chǎn)品線、服務(wù)、集群)
- 另一類標(biāo)簽,對應(yīng)資源屬性,必須唯一。(比如:IP、IDC、狀態(tài))
這樣一來,樹只是一種視圖,每次對樹的查詢,都可以動態(tài)的從海量的標(biāo)簽中組合出一棵樹。非常靈活。
只是這種設(shè)計,資源太多,海量的標(biāo)簽,計算與定制樹的速度將大大變慢。
對性能是一個比較大的考驗。筆者已經(jīng)不做服務(wù)樹很久了,一直也沒有好的機會來實踐,因此這個設(shè)想也一直沒有落實。
功能拓展
服務(wù)樹的職能其實很簡單,基本也不用拓展。能做好最核心的映射工作已經(jīng)非常好了。
在功能拓展的時候,更多的是要做減法。不能太過影響服務(wù)樹的靈活性,服務(wù)樹一旦變得臃腫,整個運維平臺都會感覺很亂。
本文腦圖
最后附上思考本文的思維導(dǎo)圖,供大家參考:
