【摘要】 服務化來自于真實世界的映射。對于微服務,我們也要尋找真實世界的隐喻。
上篇主要講服務化,下篇我們談談微服務。很顯然,服務化來自于真實世界的映射。對于微服務,我們也要尋找真實世界的隐喻。
1. 微服務,讓服務化走向專業化和精細分工。
2017年的某一天早上,我路過了一段因為修地鐵而導緻的破落的街區,又穿過稼先路與坂雪崗大道交叉路口的滾滾灰塵,轉眼看到了拐角處幸存的中國銀行。這一天,我要體驗中國銀行的服務化。大堂入口的笑容可掬的兩位美女大堂經理,證明了BOC作為四大國行之首應有的風範,也說明了其服務化能力非同小可。我要辦的業務很簡單,換幾K泰铢,作為通向一個讓我神往已久之地的盤纏。

原以為要排很長時間的隊,跟着大部隊一起等待叫号,然後在綜合視窗完成業務,沒有想到的是,BOC在外币兌換業務上實作了“微服務”,大大提升了我辦事的效率。我在一樓的自助機上完成了現彙購買,然後去到二樓,穿過一處沙發所在地,感覺一點都不像在銀行。8号視窗是外币兌換視窗,銀行職員已經等待多時,他拿走了我的銀行卡,讓我輸入密碼,然後給了我5000泰铢。
這個外币兌換視窗從綜合業務中剝離出來,成了單獨的“微服務”,着實有一些好處。
其一,是這個視窗的服務更加專業化,這個視窗的職員隻幹這一件事,效率自然高很多,因為避免了從不同的“限界上下文”中來回切換導緻的效率損失。
其二,我不會因為辦理其他業務的人太多,而排隊等候。
其三,這個視窗的職員不會因為處理了其他難纏的業務而導緻疲倦當機,影響這個視窗的業務開展。開卡櫃台的職員去噓噓了,并不會導緻這個視窗的服務中止。
其四,銀行的職員不必精通所有業務,隻要能搞定目前業務即可。
其五,我們針對這個服務的改進更加容易,我們可以優化目前的服務水準而不影響其他的服務。
很顯然,真實世界中的服務的微服務化讓服務化走向了專業化,走向了精細分工,帶來的好處也顯而易見。
2. 微服務并不是2014年才有的
誰第一個提出了微服務?看這裡:http://www.sohu.com/a/136026819_609518。然而微服務的相關理念就源遠流長了。
a. Amazon 2004年已經在實踐 Two Pizza Team,其實已經是在做微服務了。
b. 2005~2009年期間,Fred George和所在的團隊是将100萬行的傳統J2EE程式,通過解耦、自動化驗證等實踐,逐漸分解成20多個5K行代碼的小服務,又分解成200多個500行代碼的服務。在這個過程中,他們使用了基于Kafka的消息解耦服務間依賴。
後來的事情就比較清楚了,Martin Fowler 2014年3月正式喊出了Microservices的概念。
3. 小煙囪不是微服務
上篇已經提到,SOA的本質是前後分離,實作服務在分布式環境中的重用。如果我們簡單把原來非服務化的應用分拆成多個非服務化的應用,相當于把原來的大煙囪分割成很多小煙囪,那麼,連服務化都算不上,因為服務化根本的目标---在分布式環境中的重用服務,并沒有得到實作。
4. 團隊太大不是微服務
Sam Newman在“微服務設計”一書開篇就提到,微服務的初衷是解決“代碼庫過大”(或者說團隊過大)的問題。為什麼代碼庫過大是個問題?因為難以維護。通常情況下,大的代碼庫需要大的團隊維護。漫長的軟體技術發展曆史早已證明,越大的團隊越是效率低下,越是難以管理,這好像已經是不争的事實。這個世界上,真正能管理好大型軟體開發團隊的公司,基本沒有。有一些公司看起來有這個能力,但往往其軟體業務也在走下坡路,或者軟體團隊真的軟了,是以,并不見得是真正的好。
我也曾經管理過比較大的開發團隊,每天忙忙碌碌,過的很充實,但最後的效果一般。後來我終于明白了一件事情 ---“3-5個人做不好的事情,30-50人做的更爛。(騰訊雲CEO陳磊)”。
Amazon的經驗表明,6-10個人的團隊是比較合适的。
5. 團隊過小也不是微服務
有時候,我們過度的進行了“微服務化”,往往是違背了微服務的初衷和本質。微服務化其實是有代價的,這也是衆所周知的事實。
當我們把服務拆到6-10個人的小團隊可以維護的時候,就不應該繼續分拆了。如果我們将服務拆的太散,最後一個人維護10來個服務,那已經背離了初衷。我們的程式猿就是這些的服務的爹媽,這些服務出現任何問題、需求、故障, 都要爹媽來負責,想想,養那麼多孩子,容易麼?
6. 拉通過多不是微服務
前面講到團隊太大不是微服務,其實大團隊的問題并不在于大,而在于“拉通”上,“One Team,One Dream”,團隊的目标是一定的,如果要在7月份傳遞某個火車一樣的版本,各服務之間複雜的依賴關系,最終導緻兩個結果,要麼是團隊效率極低,要麼是拉而不通、痛苦不堪。
微服務強調的獨立,自治,就是盡量不要依賴其他服務,要内聚,這裡涉及到架構上的控制,架構師如果看到某些微服務總是糾纏不清,那麼應該考慮将這些微服務适當合并。
話說回來,實際情況總比理想情況複雜,總有些情況是必須依賴的,那麼應該依賴那些穩定、可靠的服務。
7. 微服務的邊界如何定義?
Martin Fowler 2003年的時候就講過,分布式架構的第一原則,就是不要分布對象。任何違背這一原則的實踐都會帶來很大的代價。N年前,我們使用了已故公司SUN專家廣為推崇的的遠端EJB技術,号稱可以更好的分離業務層和WEB層,最後下場是苦不堪言。
好的微服務設計就是在維持合适的團隊規模的前提下,盡量少的去分布對象。Eric Evans的“Domain-Driven Design”(領域驅動設計)一書值得一讀,其中提出的“Bounded Context”(限界上下文)有助于了解這一點。通常來說,一個微服務中可以包含1個或者多個 Bounded Context,但是一般不應該将一個 Bounded Context 分散到不同的微服務中。
舉個例子,對于商品交易來說,銷售和技術支援是兩個 Bounded Context,可以實作為兩個微服務。這兩個微服務中,都有 Customer 和 Product,但其保有的屬性不完全相同,Service Context 中一定要保留 Customer 的聯系方式,而Sales Context 則未必;甚至兩個 Customer 都不是同一個對象,比如買手機的 Customer 和修手機的 Customer 未必是同一個人。如果将銷售和支援放在一個單體中實作,那很可能 Customer 和 Product 兩個實體(表),會被 Sales和 Service 兩個功能共用。而在微服務架構中,他們是兩個不同的實體,各自屬性不完全相同,并很有可能存儲于不同的資料庫中,為了保持微服務的獨立性,Customer 和 Product 的資料在兩個微服務中有一定程度的備援。
那回到最初的問題,在微服務模式下,對象到底有沒有分布?答案很多時候都是沒有,就拿 Product 來說,Sales Context中的 Product 跟 Service Context 和 R&D Context 中的 Product 也不完全一緻,是可銷售的 Product ,可銷售的 Product 的資料就存儲于 Sales Context 所在的微服務中,雖然,其最終可能仍然來自 PBI 。同理, Service Context 微服務中,一般也存儲有待服務的 Product 資料。
通過合理的 Bounded Context 來引導微服務的拆分,并适當的安排資料的分布和備援,有助于提高微服務邊界劃分的合理性。
8. 微服務的代價
微服務架構小獨輕松,都是優點,難道就沒有缺點麼?當然有:
a. 系統的可用性受到比單體應用更大的挑戰。一個由10個微服務構成的系統,如果每個微服務的可用性是99%,那麼總體的可用性是99%的10次方,大概是90%左右。如何解決這個問題?答案當然是技術,通過多活、限流、容錯、熔斷等多種技術組合,來保障系統總體的可用性不受單點故障的影響。
b. 性能的下降。單體應用中本地的調用有部分會轉化成遠端調用,再牛逼的遠端調用也比本地調用要慢1個數量級以上。解決方案也不複雜,恰當的運用緩存技術來提升性能。
c. 更多的硬體資源消耗。就我們觀察到的在多個領域的實際經驗來看,應用伺服器占用的資源數量增加了數倍到數十倍。一般來說,要借用容器或者Serverless技術,來改善使用率。
9. 資料庫的獨立是不是必要的?
很多對微服務信念堅定的人認為,“資料庫不獨立不是真正的微服務”。
支援獨立的人認為:
a. 微服務強調獨立性,如果資料都不獨立,那服務不可能獨立。
b. 資料獨立之後,所有依賴都采用服務方式進行,有更好的内聚性。
c. A服務的資料庫挂了不會影響B服務。
支援不需要獨立的人認為:
a. 使用者不關心你不是獨立資料庫。使用者需要的是良好的體驗。如果分割資料庫導緻性能下降或者可用性下降,使用者可能情緒不穩定。
b. 碼農基本不希望分割資料庫。分割資料庫之後,很多原本簡單的問題,變得很複雜。
c. 架構師的擔心有時候是多餘的。在大型網際網路應用中,因為資料量巨大,要分庫分表,是以,Join一般是嚴格禁止的。而在企業級應用中,這種情況比較少。另外,有人擔心資料庫不獨立,導緻互相扯皮影響的事,畢竟還是比較少的。
看來各有道理,是以需要中庸之道來解決,資料既需要獨立,又需要共享,那怎麼辦呢?一般采用內建來解決,內建可以基于服務、JMS、資料庫內建,具體哪種方案,取決于對實時性的要求。
一般來說,主資料會被多個微服務共享,如上面例子中的 Product 和 Customer ,而交易資料則主要展現為各微服務獨享,如訂單、維修單資料。
10. 單體應用仍然是有價值的
講了這麼多微服務,這個世界上其實一直存在一個最大的反面典型,就是 Salesforce,Salesforce 其實是個巨大的單體應用。那難道 Salesforce 就不好麼?其實未必。不管白貓黑貓,能解決老鼠問題的就是好貓。
不能因為走的太遠,就忘了為什麼要出發。從根本上來說,我們要實作的目的,無非是提供更好的使用者體驗和實作更大的價值重用,從這兩個目的來說,微服務并非是唯一的途徑,而隻是一條比較流行和時尚的途徑。
正如很多兄弟所說,3MS上有100篇關于微服務的文章,各有各的看法,關于微服務的争論仍然不會停止。微服務模式的價值顯而易見,但微服務的關鍵并非技術,而是服務邊界的重新定義,我們不能過度渲染微服務的技術或者架構,而忽略了對合理的服務邊界的劃分。另外,正如開頭所講,微服務讓服務化走向專業化和精細分工,目标仍然是要實作更好的服務效率和體驗。至于架構,仍然隻有最合适的,沒有最好的。
作者:quitgame