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