我如何介紹 Microservice
我如何介紹 Microservice
遠程板磚 關註 2016.11.21 12:49* 字數 6139 閱讀 106評論 0喜歡 2本文首發於 ThoughtWorks 洞見。現在隨著我的博客一起轉到了簡書。一天我司招財貓姐(HR 大人)問我,你給我解釋一下 Microservice 是什麽吧。故成此文。一切都是從一個創業公司開始的。
第一章:從集中到分權
最近的創業潮非常火爆,我禁不住誘惑也摻和了進去,創建了一家公司。為了表達我的抱負,取千秋萬代,一統江湖之意。我給公司定下了一個非常響亮的名字叫做——一統。
故事
雖說叫做一統但是凡是都要從頭開始,公司成立之初有五個成員:羅密歐,朱麗葉,維克多,布拉伯還有老大——我。我們五個人都是工程師出身,自身具備了非常優秀的學習能力,各個都是從業務到代碼的好手,五個人一起做策劃,搞市場,寫程序,做運維,面對客戶;可謂你中有我,我中有你,努力拼搏,好不熱鬧。為了吉利,我們找了一個車庫作為機房和資料室,上至合同,下至代碼,全都放在裏面。這就是一統最初的樣子。
雖然創業艱難,大部分公司都在前兩年倒下了,但是我大一統不但沒有倒掉,還意外的得到了增長。客戶從當初的一家猛增到一百家。這樣即使我們的團隊再出色也應付不了這麽多的客戶了。掙錢還是要命呢?
micro-service-exhaust.jpg命得要,錢也得掙!怎麽辦呢?招人吧!我們絞盡腦汁搜羅(挖角)市場上的人才,組成了巨型一統團隊。我們認為我們團隊中的任何成員都應該跟初創時期的五個人一樣,能攻能守,內外兼修,但是……我們發現這是不可能的,有些人擅長寫代碼而非面對客戶,有些人善於做市場但是不喜歡算財務。後來出現了更加讓人撓頭的事情,有一個財務流程,問了5-6個人竟然沒有一個人能夠完整的串起來。於是,我一個一個的問,最後才把整個流程從這些碎片知識裏面串聯起來。
這樣的團隊的服務質量可想而知,不久就接到了數十件客戶投訴。競爭對手趁機搶占市場,一個欣欣向榮的公司瞬間就搖搖欲墜了。
micro-service-hugemono.jpg為了留住客戶,我們必須在擴張的同時能夠保證服務質量。我發現目前最重要的問題就是職責不清晰,大家不知道自己應該幹什麽也不清楚怎麽幹,於是我抽調了各個業務部分的精幹力量,總結流程,形成了客戶及市場、財務/合同、技術運維、管理團隊四個獨立的業務部分。采取內部招聘的方式將人力分配到了這四個部門中。我期望將大家從紛繁的知識體系中解脫出來,每一個不需要了解那麽多的知識,集中力量關註自己的問題以提升效率和服務質量。
在此次結構調整之後,大家的工作效率明顯提升了。抱怨知識結構太復雜,無法短期適應工作的聲音消失了。一個月之後,我們做了一個抽樣調查,發現大家對自己的工作範圍和內容都了如指掌。一些客戶又重新和我們簽訂了合同。
正當我沾沾自喜的時候,發生了一個重大事件。由於我們的資料室是對全公司開放的,任何成員都可以查看或修訂其中的信息。客戶及市場部的一個員工平時非常好學,對財務方面的知識掌握的非常系統。有一天,公司急需草擬一份財務清單,但是這個任務非常耗時,財務部門的同時當時正在月末審核,無暇抽身。這位熱心的同學就憑借自己出色的能力從資料室取來相應的材料完成了清單。三天後,財務部的羅密歐準備細化這個清單。但是清單的內容讓他著實吃了一驚——清單上的填寫內容和他們部門內約定格格不入。羅密歐只得自己重新完成了清單。一來一去讓他的工作耽擱了一天,羅密歐向我抱怨道。無獨有偶,其他部門也發生了同樣的事情。這讓我意識到只是把人員的職責進行劃分並不能徹底解決問題。我們不能再繼續混用一個資料室了,因為這樣人人都可以任意修改各種資料,安全性不好不說還會造成填寫格式混亂。於是我把財務部的資料放在了另一個獨立的屋子裏,並給羅密歐單獨配了鑰匙。這樣,任何想填寫財務清單的人只能找財務部的人所要單據,而當單據繳回的時候也必須經過財務部的審核。鑒於財務部每個月底都會很忙,在那時我會臨時抽調人手去幫忙。
我希望對其他部門做相應的整改,但這種動作幅度畢竟很大,因此,一段時間內還會有多個部門共用資料室。經過一個月的努力,我們最終還是淘汰了公用資料室。為每一個部門都配備了獨立資料室。雖然需要繳納更多的房租,但是各部門再也沒有犯之前的錯誤。
micro-service-isolation.jpg從故事到項目
大多數項目也會像我們的創業公司一樣,一開始大家一起幹活,每一個人都是沖鋒陷陣多面手。大家一起組成了應用程序的全部,而我們的車庫就是數據庫。這種組織結構代表了典型的 monolitic application。這種系統的邏輯架構是類似這樣的。
micro-service-initial-map.jpg在項目的早起,業務簡單,吞吐不大,這種結構清晰,易於理解的架構非常實用。但是隨著業務的增大,混在一起的代碼不易理解。而最容易想到的解決辦法就進行職責的劃分。一統公司一開始在維持車庫結構的情況下僅僅把人員上做了拆分。這種情形在實際項目中也存在。系統進入了多個服務共享一個數據庫的階段,而集成點在數據庫上。
micro-service-dbint-map.jpg這種職責劃分但又維持數據庫集成的方式只應當作為過度階段存在。程序永遠都是邏輯+數據,而數據的混雜談不上職責的獨立。長期維持這種數據集成的狀態容易出現業務下行,數據表達不一致等問題。從邏輯+數據的整體劃分邊界(稱為模塊,或者服務)勢在必行。而在邊界劃定之後,就需要考慮獨立的服務之間如何進行協作了。
第二章:協作
現在我們的資料室都獨立了,再也沒有辦法像以前一樣有需要就去公共資料室裏取資料了。那麽我們應該如何進行協作呢?
故事
一個非常自然的想法是把各部門用業務流程穿起來。例如,如果洽談一個訂單,先由客戶及市場部進行調查和談判,然後由技術部制定解決方案,管理部審批之後由財務合同部擬定合同,最終遞交管理部簽署。這種協作方式我們不妨叫他 串聯協作。
micro-service-serial.jpg為了將這一方案執行下去,我們對各個部門的人員進行了培訓。例如,對於對於技術部,如果是洽談一個訂單,那麽技術部需要給出解決方案,完成之後需要將方案遞交管理部審批。類似的業務有很多,每一個業務各個部門任務都不同,而下遊接收的部門也不一樣。但是我的同事們還是克服了困難,將它們爛熟於胸。
業務變化是最平常的,一變就是一大把。現在對於洽談訂單的業務,我們需要在技術方案給出之後先給財務部進行預算審核再遞交管理部。這需要重新培訓三個部門的人,洗腦一樣的把他們之前的流程抹掉。一個業務變化還好,但是一下二三十個業務發生變化讓大家抓狂。甚至有人說這和之前一大坨人一起做所有事情的時候沒有什麽差別。看來這種業務串聯的方式是行不通了。
所謂我不入地獄誰入地獄,這種情況下我挺身而出,入住市場部——因為這個部門是直接為客戶服務的。我對所有的流程了如指掌,當業務來了的時候,有我去對業務進行協調。例如,當一個洽談訂單的業務到來的時候,我會先將他交給客戶市場部進行談判;結束後市場部將需求和意向書交給我,我再把需求交給技術部去制定解決方案;方案制定完畢之後技術部會把方案返回給我,我再把結果交給財務部審核…如此進行。這樣,每一個部門就不會由於業務變化重新接受培訓了,也不用記住他們的下遊應該是誰。大家覺得,職責明確多了,工作輕松多了。
micro-service-composer.jpg這種協作方式我們不妨稱之為 業務調度員 式的協作。
現在我儼然成為了流程的中心,其他業務部門不需要關註業務流程的變化。這給我們增加了很多靈活性,因為我一個人的變化速度要比一群人的變化速度快得多(你是獨裁者嗎餵)。但是我的大腦總是有限的,一年之後,經歷了三四輪的業務變化,我已經開始不能準確的回憶某些業務細節。我不得不開始頻繁的查詢我的業務筆記來確定我的下一步操作;此外,不停的往各部門送信也令我不堪重負。這時候,我希望其他人能夠為我分擔。我決定化被動為主動,不由我主動聯絡各個部門,而由各個部門主動接受任務。我在公司安裝了一個 大喇叭,話筒就在我的辦公室裏。當一個訂單洽談業務到來的時候我就朝著喇叭嚎:新訂單來啦。客戶和市場部專門關註新訂單,因為按照流程,訂單到來之後市場部要盡快投入談判。於是他們會主動開始行動。當市場部工作完畢之後,他們會將談判的結果、需求以及意向書拿到我的辦公室裏。我會再嚎:需求來啦。此時,技術部會從我這裏拿走這些資料資料並開始工作。如此往復,直到項目完成。
micro-service-event.jpg這種協作方式令我不必再操心信息在各部門之間的流轉。各部門知道他們應該何時介入,我只需要對著大喇叭喊自然會有相關的部門將活幹完。這樣,我作為業務的中轉中心,工作量不會隨著業務的增長顯著的增大(只要喊話就行了,至多就是增加喊話種類),而各部門也不用關心自己的下遊到底是誰,只需要關心我喊的話就行了。這種協作方式不妨稱之為 公司廣播。看起來這是一種非常方便的形式。但是這真的就又快又省嗎?
有一天,來了一個新的訂單。在我接到意向書和需求之後,我照例喊話:需求來啦!接著,我就出去吃飯了(真是資本家啊你)。等我回到了辦公室,發現文檔已經被拿走了,而結果還沒有送過來。時間一天一天過去了,我手頭的新訂單越積越多,需求文檔和意向書源源不斷的送過來。到了第三天我實在是受不了了,想去查找文檔的去向和任務的完成狀況。這時候我才發現我根本無從下手,因為我不知道文檔是誰拿走的,於是我便一個部門一個部門的去詢問。可是由於業務的發展,現在我們已經有20多個部門了,這種非常規的詢問不僅讓我跑斷了腿,而且為了查證,需要翻閱各部門成噸的業務日誌,各部門的部長對此也頗有微辭。我終於意識到——這種協作方式在令結構松散靈活的同時也極大的增加了監管的難度。必須采取額外的投入來彌補這一短板。
於是,專門監視各部門動向的“紀檢委”:監管部出現了。一開始,我只是想確認一下各部門運作是否正常,有沒有由於天災人禍而出現團滅的現象。出於不對各部門添加新的壓力的願望,監管部會定期去確定各部門走一圈看看是否都在好好幹活(真是討人嫌的部門啊),就像這樣。
micro-service-monitor-pull.jpg但是隨著業務的發展,我希望得到各個部門更加詳盡的信息,例如,各部門是否積壓了大量任務而需要幫助,在處理過程中是否由於流程不合理而無法繼續下去等等。需要收集的數據已經遠遠超過了監管部跑腿的速度。怎麽辦呢?如果我手頭沒有什麽錢,我可能會降低監管部工作的周期,例如之前是半天一次,現在改成兩天一次。但是我是土豪,於是我制定了監管匯報單,強制各部門在狀況出現問題的時候主動向監管部匯報,就像這樣。
micro-service-monitor-push.jpg從故事到項目
我們真正的開始考慮服務之間如何進行協作了。和一統公司的做法一樣,最容易想到的就是業務串聯。業務首先由第一個服務處理,處理之後第一個服務調用第二個服務繼續處理,直至業務全部處理完畢。這樣,我們就得到了這樣的系統架構:
micro-service-serial-map.jpg正如故事中說的一樣,這種業務的串聯難以應對業務流發生的變化。同時,由於服務之間互相直接耦合,集成點多,難以做到獨立進行部署。業務調度員 的方式是一種很好的改進。如果你還記得那位勤勞的調度員(我),那麽你就一定認識 Composer 這個特殊的服務:我們使用 它進行業務流的分發與控制。這樣,服務僅僅和 composer 進行對接,不需要考慮業務流的問題。既明確了職責又可以進行獨立部署。以下就是這種協作方式的架構:
micro-service-composer-map.jpg而最復雜的 公司廣播 則是變直接調用為事件觸發。使用 事件 隔離了各自的模型。系統結構更加松散靈活。
micro-service-event-map.jpg隔離和協作的矛盾
從躊躇滿誌的創業開始到現在,我感慨於業務的擴大和公司規模的發展。也有一些會議例如 PCon 希望我們能夠去介紹的結構劃分和協作模式。但是每當我在工作之余靜靜思考的,卻感到一些厭倦。我們的協作真的好嗎?隨著職責的劃分,我們越來越專業化,互不影響的工作方式極大的增加了我們的效率,良好的隔離讓我們的失誤不至於擴散並能夠橫向擴展;而監控系統也告訴我們一切盡在掌握。但是隔離同時也是壁壘。為了協作,我們在這些壁壘上開了些小孔,為了嚴格控制進出,我們制定了越來越多的規條,例如,信件應該怎麽寫,單據應該怎麽填。回頭看去,成百上千的規約連我也不能盡數,當我需要對我的公司做出變化的時候,如果變化僅僅發生在各個部門內部,這種結構的優勢就顯露無遺。但是如果設計到部門之間的協作,甚至部門的拆分合並,就會變得異常艱難。由於部門和規約的耦合是存在於腦內的,並不顯露在外,修改已經存在的規約和部門結構往往不現實,只能花更多的錢去組建新的部門,逐步介入公司業務後淘汰舊有的部門。而這種周期動輒是以月計算的。有的時候,可能寧可去接受新的方式從頭開始,賣掉舊的公司,創建新的公司,然後繼續輪回。
隔離既創造了靈活的單點變化也擴展造就了整體的僵化。細小的部門劃分不能解決這個問題,因為部門越多,規約越多,實施成本越高(在例子中我們並沒有考慮資料室的房租,監控的支出,但是現實中這往往是一個決定性因素)。單個部門結構的簡化造就了整體的復雜。
因此,分部門就一定好嗎?業務調度員就沒有公司廣播好嗎?答案應該來源於你的現實,而不是理論。如果讓我重來一次,我可能會慢一點,再慢一點。未來無法預計,針對當下的痛點做出反應可能不是最優的,但是卻是一個容易理解的思路。
實際項目中也是一樣。就像武俠小說中的一樣,威力越大的招數其使用限制也就越多。一方面,系統結構越來松散越靈活,變化變得容易;另一方面,系統越來越復雜,維護越來越困難。當維護困難到一定程度不得不將其提上議事日程的時候專事監督與維護的工作就出現了,這種維護不同以往。維護者既要有維護知識又必須了解這個復雜系統的運作方式。別忘了,虛擬化、雲、Devops 除了概念上的光鮮又復雜又花錢啊!
慢慢進化,慎重的考慮並決定是否選用 Microservice,然後做好維護吧。
第三章:Microservice
在前面的內容中,哪種方式可以稱為 microservice 架構呢?故事裏面公司組織結構演化分成了幾個部分,並不是每一個階段代表的結構都可以稱之為 microservice:
- 第一個階段是多個部門共用一個資料室,這種情況往往並沒有擺脫數據庫集成的事實(有些項目使用 Schema 對訪問進行隔離,不在此列),不能稱為 microservice;
- 第二個階段是各個部門有自己的資料室,這是一個非常重要的改變,直到此時,各個部門才實現了完全的隔離,但是還足以稱為 microservice;
- 第三個階段分三類:
- 首先是串聯協作。在這種方式下,一個部門的變化往往影響了其他部門,因為每一個部門都需要知道業務的上遊部門和下遊部門,因此有比較緊密的耦合關系,無法獨立變化。因此不足以稱為 microservice;
- 其次是業務調度員。這種方式下部門自身的變化不會擴散到其他部門,因此是可以獨立決定和操作,只要部門足夠小,這種結構可以稱之為 microservice了;
- 第三是公司廣播。這種方式下的部門耦合更加松散,可以獨立進行變化,在部門足夠小的前提下可以稱之為 microservice。
我們的初衷是什麽呢?構造一個系統能橫向擴展以滿足業務伸縮性,提供靈活變化的能力,又希望變化的影響不要擴散。因此,如果一個架構可以稱之為 microservice 架構,那麽意味著:
- 每一個 Service 可以進行獨立部署;
- 每一個 Service 都足夠小,完成完整的定義清晰的職責;
業務調度員和公司廣播兩個例子的組織結構都可以成為 microservice 架構。但是他們之間並沒有絕對的優劣之分。選用哪一種應當取決於實際要求。
寫在最後
Microservice 不是一種科學,而僅僅是實踐。就像是 OO 一樣。最終應當是需求,是人,決定架構而非架構決定需求。Microservice 是為 Business Capability 而建,是根據實際(或者痛點)做出的抉擇。他解決了一些問題,但是並不能肯定就是今後軟件的發展方向。硬件的革新——不論是近期的電池技術的發展,還是近乎黑科技的量子態傳輸,量子計算都有可能影響甚至顛覆今天形成的軟件開發手段。就像是當年大家為了追求極致的執行效率試圖將代碼塞進 64K 的代碼段一樣,我們今天奉為經典的東西未來可能只是茶余飯後的談資。我們能做的只有保持開放的心態,堅持辯證的觀點,堅持從實際出發(我當年政治一定得高分了),尋找出最合適的解決方案。這也就是我們不稱自己為碼農的理由之一吧。
https://www.jianshu.com/p/cad612631ec5
我如何介紹 Microservice