作者:禚嫻靜
這兩年,微服務(wù)架構(gòu)火了。在國內(nèi),從消費(fèi)級(jí)互聯(lián)網(wǎng)應(yīng)用,到企業(yè)級(jí)應(yīng)用;從金融領(lǐng)域,到電信領(lǐng)域;從新開發(fā)系統(tǒng)到已經(jīng)開發(fā)了十幾二十年的遺留系統(tǒng);一夜之間,好像所有的團(tuán)隊(duì)都在談微服務(wù)。
然而,我們?yōu)槭裁床捎梦⒎?wù)呢?
是的,讓我們的系統(tǒng)盡可能快地去響應(yīng)變化。其實(shí)幾十年來我們一直在嘗試解決這個(gè)問題。如果一定要在前面加個(gè)限制的話,那就是低成本的快速響應(yīng)變化。上世紀(jì)九十年代Kent Beck提出要擁抱變化,在同期出現(xiàn)了諸多輕量級(jí)開發(fā)方法(諸如 XP、Scrum);2001年敏捷宣言誕生,之后又出現(xiàn)了精益、看板等新的管理方式。如果說,這些是為了盡快的響應(yīng)變化,在軟件開發(fā)流程和實(shí)踐方面提出的解決方案,那么微服務(wù)架構(gòu)就是在軟件技術(shù)和架構(gòu)層面提出的應(yīng)對(duì)之道。
微服務(wù)是如何做到的?
微服務(wù)是一種架構(gòu)模式,它提倡將單一應(yīng)用程序劃分成一組小的服務(wù),服務(wù)之間互相協(xié)調(diào)、互相配合,為用戶提供最終價(jià)值。每個(gè)服務(wù)運(yùn)行在其獨(dú)立的進(jìn)程中,服務(wù)與服務(wù)間采用輕量級(jí)的通信機(jī)制互相溝通(通常是基于HTTP協(xié)議的RESTful API)。每個(gè)服務(wù)都圍繞著具體業(yè)務(wù)進(jìn)行構(gòu)建,并且能夠被獨(dú)立地部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等。另外,應(yīng)當(dāng)盡量避免統(tǒng)一的、集中式的服務(wù)管理機(jī)制,對(duì)具體的一個(gè)服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文,選擇合適的語言、工具對(duì)其進(jìn)行構(gòu)建。
— James Lewis and Martin Fowler
這是James和Martin2014年在《微服務(wù)》一文中提到的對(duì)于微服務(wù)的定義。相對(duì)于單體架構(gòu)和SOA,它的主要特點(diǎn)是組件化、松耦合、自治、去中心化,體現(xiàn)在以下幾個(gè)方面:

- 一組小的服務(wù)
服務(wù)粒度要小,而每個(gè)服務(wù)是針對(duì)一個(gè)單一職責(zé)的業(yè)務(wù)能力的封裝,專注做好一件事情。
- 獨(dú)立部署運(yùn)行和擴(kuò)展
每個(gè)服務(wù)能夠獨(dú)立被部署并運(yùn)行在一個(gè)進(jìn)程內(nèi)。這種運(yùn)行和部署方式能夠賦予系統(tǒng)靈活的代碼組織方式和發(fā)布節(jié)奏,使得快速交付和應(yīng)對(duì)變化成為可能。
- 獨(dú)立開發(fā)和演化
技術(shù)選型靈活,不受遺留系統(tǒng)技術(shù)約束。合適的業(yè)務(wù)問題選擇合適的技術(shù)可以獨(dú)立演化。服務(wù)與服務(wù)之間采取與語言無關(guān)的API進(jìn)行集成。相對(duì)于單體架構(gòu),微服務(wù)架構(gòu)是更面向業(yè)務(wù)創(chuàng)新的一種架構(gòu)模式。
- 獨(dú)立團(tuán)隊(duì)和自治
團(tuán)隊(duì)對(duì)服務(wù)的整個(gè)生命周期負(fù)責(zé),工作在獨(dú)立的上下文中,自己決策自己治理,而不需要統(tǒng)一的指揮中心。團(tuán)隊(duì)和團(tuán)隊(duì)之間通過松散的社區(qū)部落進(jìn)行銜接。
我們可以看到整個(gè)微服務(wù)的思想就如我們現(xiàn)在面對(duì)信息爆炸、知識(shí)爆炸是一樣的:通過解耦我們所做的事情,分而治之以減少不必要的損耗,使得整個(gè)復(fù)雜的系統(tǒng)和組織能夠快速的應(yīng)對(duì)變化。
My First Law of Distributed Object Design: Don’t distribute your objects (From P of EAA). - Martin Fowler
然而談到微服務(wù),我們不能忽視的一點(diǎn)是:微服務(wù)仍然是典型的分布式系統(tǒng),它必然有分布式系統(tǒng)固有的問題:諸如怎么部署,出錯(cuò)怎么辦,怎么保證數(shù)據(jù)的最后一致性;與此同時(shí),還有服務(wù)要多微?業(yè)務(wù)變化后服務(wù)如何調(diào)整?服務(wù)規(guī)?;笤趺崔k?如何避免一個(gè)服務(wù)改動(dòng)導(dǎo)致的多個(gè)級(jí)聯(lián)服務(wù)的失???如何進(jìn)行測(cè)試等等問題。
“微服務(wù)不是免費(fèi)的午餐”。從實(shí)戰(zhàn)中我們清楚地認(rèn)識(shí)到選擇任何架構(gòu)都有利有弊,服務(wù)化也是一樣。企業(yè)從微服務(wù)架構(gòu)獲益的同時(shí),必然要面對(duì)切換到由眾多服務(wù)組成的分布式系統(tǒng)后所帶來的挑戰(zhàn)。我們認(rèn)為只有提升團(tuán)隊(duì)?wèi)?yīng)對(duì)這些挑戰(zhàn)的成熟度,才能真正使企業(yè)從這種微服務(wù)架構(gòu)中獲益.
那么對(duì)于即將和已經(jīng)開始實(shí)施微服務(wù)的團(tuán)隊(duì),應(yīng)該如何應(yīng)對(duì)呢?結(jié)合我們項(xiàng)目的經(jīng)驗(yàn),我認(rèn)為應(yīng)從DevOps、服務(wù)構(gòu)建、團(tuán)隊(duì)和文化四點(diǎn)入手:
- 首先需要考慮構(gòu)建DevOps能力,這是保證微服務(wù)架構(gòu)在持續(xù)交付和應(yīng)對(duì)復(fù)雜運(yùn)維問題的動(dòng)力之源;
- 其次保持服務(wù)持續(xù)演進(jìn),使之能夠快速、低成本地被拆分和合并,以快速響應(yīng)業(yè)務(wù)的變化;
- 同時(shí)要保持團(tuán)隊(duì)和架構(gòu)對(duì)齊。微服務(wù)貌似是技術(shù)層面的變革,但它對(duì)團(tuán)隊(duì)結(jié)構(gòu)和組織文化有很強(qiáng)的要求和影響。識(shí)別和構(gòu)建匹配架構(gòu)的團(tuán)隊(duì)是解決問題的另一大支柱。
- 最后,打造持續(xù)改進(jìn)的自組織文化是實(shí)施微服務(wù)的關(guān)鍵基石。只有持續(xù)改進(jìn),持續(xù)學(xué)習(xí)和反饋,持續(xù)打造這樣一個(gè)文化氛圍和團(tuán)隊(duì),微服務(wù)架構(gòu)才能持續(xù)發(fā)展下去,保持新鮮的生命力,進(jìn)而實(shí)現(xiàn)我們的初衷。
在本文中會(huì)針對(duì)第一點(diǎn),并以我們項(xiàng)目微服務(wù)的發(fā)展歷程為例介紹我們遇到的各種坑和采取的相關(guān)措施,希望能夠給正在準(zhǔn)備實(shí)施和已經(jīng)實(shí)施微服務(wù)的團(tuán)隊(duì)一些借鑒。
背景

我們于2012年在系統(tǒng)集成需求的驅(qū)動(dòng)下走上了服務(wù)化之路,通過將重復(fù)的業(yè)務(wù)能力封裝在幾個(gè)服務(wù)之間完成了系統(tǒng)集成,并成功上線。最初只有8個(gè)服務(wù)支持我們的業(yè)務(wù)系統(tǒng),服務(wù)與服務(wù)之間采取基于HTTP的RESTful API的方式進(jìn)行通信,通過自動(dòng)化腳本將應(yīng)用部署到生產(chǎn)環(huán)境。

在隨后的2年中我們的業(yè)務(wù)快速發(fā)展,增加到了60多個(gè)站點(diǎn)和服務(wù)。服務(wù)的上線周期也越來越短,從兩年到兩周。而這樣的一套生產(chǎn)環(huán)境是由客戶的2名運(yùn)維人員手工維護(hù)的(包括基礎(chǔ)設(shè)施構(gòu)建),每次發(fā)布都會(huì)存在大量的人工干預(yù),比如對(duì)部署結(jié)構(gòu)和系統(tǒng)權(quán)限的修改等,給我們的整個(gè)生產(chǎn)部署和運(yùn)維帶來了較大的問題:
- 大量的人工干預(yù),頻頻出錯(cuò)。
手工方式始終是易錯(cuò)和低效的,而且會(huì)導(dǎo)致各種難以重現(xiàn)的環(huán)境問題(就如雪花服務(wù)器),這使得一些復(fù)雜點(diǎn)的運(yùn)維工作,包括技術(shù)平臺(tái)的整體升級(jí)、災(zāi)備系統(tǒng)搭建等很難開展,往往要提前半年甚至一年來進(jìn)行籌備。當(dāng)我們服務(wù)規(guī)?;桶l(fā)布周期縮短之后,它帶來的傷害又進(jìn)一步明顯起來。為了減小這種傷害,業(yè)務(wù)部門不得不降低發(fā)布頻率,從兩周延遲到一個(gè)月,因此也影響到了對(duì)最終用戶的響應(yīng)速度,并不得不采取Hotfix的方式來修正發(fā)布速度的問題,實(shí)際上又增加了問題的復(fù)雜度。
- 缺乏有效的監(jiān)控和日志管理,產(chǎn)品環(huán)境定位困難。
沒有監(jiān)控,無法及時(shí)知曉服務(wù)的運(yùn)行狀態(tài)。很多問題直到最終用戶才能發(fā)現(xiàn),問題反饋周期很長。同時(shí),運(yùn)維人員不懂開發(fā)人員的服務(wù)設(shè)計(jì)和調(diào)用流程,開發(fā)人員不懂產(chǎn)品環(huán)境的配置結(jié)構(gòu)。當(dāng)產(chǎn)品環(huán)境出錯(cuò)之后,往往要花費(fèi)數(shù)小時(shí)才能定位到問題根源。
另外,負(fù)載均衡和單點(diǎn)服務(wù)降級(jí)無法真正開展,當(dāng)一個(gè)服務(wù)出現(xiàn)問題時(shí),需要關(guān)掉其所在的服務(wù)器。產(chǎn)品環(huán)境資源利用率低,運(yùn)維成本居高不下。
2015年初,當(dāng)我們遇到了Powershell的bug和服務(wù)不能正常啟動(dòng)的貌似隨機(jī)問題時(shí),就如遇到了那根壓倒駱駝的最后一根稻草,客戶對(duì)我們明確的提出“不要再添加任何一個(gè)服務(wù)了”。
殘酷的事實(shí)再一次向我們證明,在這樣一個(gè)復(fù)雜系統(tǒng)下,傳統(tǒng)的手工運(yùn)維方式必然要被淘汰,微服務(wù)的實(shí)施有一定的先決條件:基礎(chǔ)的運(yùn)維能力(如監(jiān)控、快速配置、快速部署)需提前構(gòu)建,否則就會(huì)陷入像我們一般如此被動(dòng)的局面。而我們也看到,當(dāng)服務(wù)規(guī)?;笮枰嘧詣?dòng)化和標(biāo)準(zhǔn)化的手段來提升效能和降低成本。
服務(wù)治理
隨后的一段時(shí)間,我們的團(tuán)隊(duì)重新梳理了最后一公里和運(yùn)維的需求,如下圖所示,并開始服務(wù)治理,從而構(gòu)建支撐當(dāng)下架構(gòu)的交付和運(yùn)維能力。

1. 基礎(chǔ)環(huán)境的準(zhǔn)備
環(huán)境需要能夠快速的創(chuàng)建并啟用全新的服務(wù),能夠快速對(duì)現(xiàn)有的環(huán)境進(jìn)行自動(dòng)更改等,以保持各環(huán)境的一致性。我們推薦采用基礎(chǔ)設(shè)施及代碼的實(shí)踐,通過代碼來描述計(jì)算和網(wǎng)絡(luò)基礎(chǔ)設(shè)施的方法,使得圖案度i可以快速安全的搭建和處理由新的配置代替的服務(wù)器,服務(wù)器之間可以擁有更高的一致性,降低了在“我的環(huán)境工作,而你的環(huán)境不工作”的可能,也是為后續(xù)的發(fā)布策略和運(yùn)維提供更好的支撐。
在技術(shù)層面,隨著云平臺(tái)技術(shù)的成熟,Docker和圍繞Docker生態(tài)圈的形成,開發(fā)和運(yùn)維團(tuán)隊(duì)如虎添翼。組織可以根據(jù)現(xiàn)狀選擇合適的方式逐步遷移到云平臺(tái)。另外,對(duì)于目前不能采用Docker技術(shù)的Windows平臺(tái),Chef、Ansible也是不錯(cuò)的選擇。
2. 發(fā)布部署
要求服務(wù)能夠快速上線,能夠快速部署到各個(gè)環(huán)境以便盡快得到驗(yàn)證。面對(duì)如此龐大的服務(wù)及復(fù)雜的依賴關(guān)系,我們建議分離產(chǎn)品、預(yù)發(fā)布環(huán)境及測(cè)試環(huán)境。采用部署流水線,由自動(dòng)化腳本實(shí)現(xiàn)全環(huán)境的快速部署,包括配置管理、版本管理等。
3. 運(yùn)行時(shí)監(jiān)控與業(yè)務(wù)運(yùn)營
當(dāng)產(chǎn)品環(huán)境出錯(cuò)時(shí),需要快速的定位問題,檢測(cè)可能發(fā)生的意外和故障。而監(jiān)控是快速定位和預(yù)防的不二選擇,在微服務(wù)架構(gòu)中更是至關(guān)重要。監(jiān)控包括服務(wù)可用狀態(tài)、請(qǐng)求流量、調(diào)用鏈、錯(cuò)誤計(jì)數(shù)等內(nèi)容,以便發(fā)現(xiàn)問題及時(shí)修復(fù),實(shí)時(shí)調(diào)整系統(tǒng)負(fù)載,進(jìn)行必要服務(wù)降級(jí),過載保護(hù)等等,從而讓系統(tǒng)和環(huán)境提供高效高質(zhì)量的業(yè)務(wù)服務(wù)。其中健康狀態(tài)頁面、結(jié)構(gòu)化的日志、實(shí)時(shí)服務(wù)依賴關(guān)系可視化、流量統(tǒng)計(jì)、事件機(jī)制等都是監(jiān)控領(lǐng)域可采取的基礎(chǔ)技術(shù)手段。
除此,隨著服務(wù)越來越多,需要進(jìn)一步考慮藍(lán)綠部署、灰度發(fā)布、服務(wù)安全、容器編排等問題和自動(dòng)化標(biāo)準(zhǔn)化的手段,從而更好的管理大規(guī)模下服務(wù)產(chǎn)生的運(yùn)維需求。下圖是最近幾期ThoughtWorks技術(shù)雷達(dá)中提到的相關(guān)內(nèi)容,可供不同技術(shù)棧和處于不同實(shí)施階段的團(tuán)隊(duì)參考:

我們的選擇和改進(jìn)

針對(duì)上面的幾個(gè)痛點(diǎn)和我們項(xiàng)目所處的階段,結(jié)合項(xiàng)目.NET技術(shù)棧的生態(tài)系統(tǒng),我們主要采用Chef自動(dòng)化構(gòu)建本地構(gòu)建的基礎(chǔ)設(shè)施,與運(yùn)維團(tuán)隊(duì)一起優(yōu)化部署流程,提供服務(wù)健康狀態(tài)頁面支持監(jiān)控,使用Splunk進(jìn)行集中式日志管理,并可視化服務(wù)依賴關(guān)系等來進(jìn)行全面服務(wù)治理,我們的部署時(shí)間從原來的十幾個(gè)小時(shí)縮短到三十分鐘,成功率也大大提高。結(jié)合業(yè)務(wù)部門的需求和現(xiàn)狀的分析,對(duì)其方面地要求,如獨(dú)立部署、配置管理、服務(wù)發(fā)現(xiàn)、過載保護(hù)等的改進(jìn)仍在繼續(xù)中。
除此之外,我們還做了什么?
You build it, you own it. - Amazon CTO
打造DevOps文化,將運(yùn)維作為需求提前注入到開發(fā)流程

從上一節(jié)可以看出,微服務(wù)對(duì)開發(fā)人員和運(yùn)維人員的工作方式和技能都有新的要求,帶來很強(qiáng)的沖擊。在2014年隨后的一段時(shí)間,我們開始將運(yùn)維的需求內(nèi)建到整個(gè)開發(fā)流程。當(dāng)新業(yè)務(wù)需求提出的時(shí)候會(huì)同時(shí)交給開發(fā)人員和運(yùn)維人員,后者將整個(gè)運(yùn)維環(huán)境的要求(包括監(jiān)控和安全)進(jìn)行分析,產(chǎn)出約束規(guī)范或非功能需求遞給開發(fā)人員;開發(fā)人員在做技術(shù)決策和開發(fā)工作時(shí)遵循這些約束并滿足這些非功能需求,最后將整個(gè)產(chǎn)品以及監(jiān)控的實(shí)現(xiàn)交付給運(yùn)維團(tuán)隊(duì)。雙方同時(shí)也重建了溝通計(jì)劃,互換技術(shù)架構(gòu)和運(yùn)維方面的知識(shí),互相支持和深入合作。
在我們整個(gè)服務(wù)治理的過程中,花了大量的時(shí)間去理順最后一公里和運(yùn)營監(jiān)控的問題,與運(yùn)維團(tuán)隊(duì)的合作一步步從無到有,從不信任不合作到逐漸改善,才使得微服務(wù)的實(shí)施順利進(jìn)階??梢哉f在企業(yè)內(nèi)要成功實(shí)施微服務(wù),最不能少的合作角色就是企業(yè)的運(yùn)維團(tuán)隊(duì)。微服務(wù)實(shí)施要想順利進(jìn)行,必須要打破開發(fā)團(tuán)隊(duì)和運(yùn)維團(tuán)隊(duì)之間的高墻,真正做到“開發(fā)自運(yùn)維”,運(yùn)維自開發(fā),互生互長。我們也向其他的組織推薦這樣的方式,打通DevOps的任督二脈,為微服務(wù)保駕護(hù)航。
擴(kuò)展閱讀:
- http://martinfowler.com/microservices/
- http://martinfowler.com/bliki/MicroservicePrerequisites.html
- http://martinfowler.com/bliki/InfrastructureAsCode.html
- https://www.thoughtworks.com/insights/blog/microservices-evolutionary-architecture
- http://liguanglei.name/blogs/2015/04/22/devops-chinese-name/
- https://www.thoughtworks.com/insights/blog/macro-trends-technology-industry
原文發(fā)布于:微服務(wù)的團(tuán)隊(duì)?wèi)?yīng)對(duì)之道