阿里云2020年從架構(gòu)談起到Mesh結(jié)束,阿里云最新規(guī)劃消息阿里云2020年從架構(gòu)談起到Mesh結(jié)束作者 張羽辰(同昭)阿里云交付專(zhuān)家導(dǎo)讀:如今,幾乎所有的事情都離不開(kāi)軟件,當(dāng)你開(kāi)車(chē)時(shí),腳踩上油門(mén),實(shí)際上是車(chē)載計(jì)算機(jī)通過(guò)力度感應(yīng)等計(jì)算輸出功率,最終來(lái)控制油門(mén),你從未想過(guò)這會(huì)是某個(gè)工程師的代碼。當(dāng)我們談?wù)摷軜?gòu)時(shí),我們到......
作者 張羽辰(同昭)阿里云交付專(zhuān)家
導(dǎo)讀:如今,幾乎所有的事情都離不開(kāi)軟件,當(dāng)你開(kāi)車(chē)時(shí),腳踩上油門(mén),實(shí)際上是車(chē)載計(jì)算機(jī)通過(guò)力度感應(yīng)等計(jì)算輸出功率,最終來(lái)控制油門(mén),你從未想過(guò)這會(huì)是某個(gè)工程師的代碼。
當(dāng)我們談?wù)摷軜?gòu)時(shí),我們到底在談?wù)撌裁?/strong>
面向?qū)ο缶幊毯瘮?shù)式模塊化設(shè)計(jì)微服務(wù)這些詞匯貌似都和架構(gòu)這個(gè) buzzword 有點(diǎn)關(guān)系,的確我們這個(gè)領(lǐng)域充滿了很多難以理解的詞匯,這些詞匯從英語(yǔ)翻譯到中文已經(jīng)喪失了部分上下文,再隨著上下文的改變使得意義徹底扭曲,比如:引擎、框架、架構(gòu)、應(yīng)用、系統(tǒng)……誠(chéng)然大家都或多或少對(duì)這些詞語(yǔ)達(dá)成共識(shí),在工作中使用這些詞匯進(jìn)行溝通,某時(shí)就是指“我們都懂的那個(gè)東西”,但是在我深入的想聊聊架構(gòu)或者說(shuō)軟件架構(gòu)時(shí),的確不得不問(wèn)自己這個(gè)問(wèn)題,我們到底是談?wù)撌裁?/p>
事實(shí)上,架構(gòu)這個(gè)詞根據(jù)上下文所確定的范圍較為固定,建筑學(xué)上的架構(gòu)指代房屋結(jié)構(gòu)、整體設(shè)計(jì)、組合構(gòu)成等,而這些 highlevel 設(shè)計(jì)往往并不需要全面了解底層,就像使用 RestTemplate 進(jìn)行 WebService 調(diào)用時(shí),我們也不關(guān)心 socket 是在四層連接的一樣,因?yàn)榧?xì)節(jié)被隱藏了。
但是,建筑學(xué)上的架構(gòu)與軟件架構(gòu)卻又極大的不同之處,問(wèn)題出現(xiàn)在“軟件”這個(gè)詞上,按照 software 的詞解,ware 是指產(chǎn)品一樣的東西,而 soft 則強(qiáng)調(diào)易變,這是與 hardware 所對(duì)應(yīng)的。我們希望“軟件”能夠進(jìn)行快速的修改,應(yīng)該能夠快速響應(yīng)甲方或者客戶的需求,所以軟件架構(gòu)必然不像建筑架構(gòu)一樣,建筑一經(jīng)建成,修改的成本極高,而軟件應(yīng)該走對(duì)應(yīng)的方向,發(fā)揮易于修改的特點(diǎn)。
“現(xiàn)在的大多數(shù)軟件非常像埃及金字塔,在彼此之間堆建了成千上萬(wàn)的磚塊,缺乏結(jié)構(gòu)完整性,只是靠蠻力和成千上萬(wàn)的奴隸完成?!?—— Alan Kay。筆者認(rèn)為,雖然這句話表達(dá)的意思我很贊同,但實(shí)際上,金字塔作為帝王的陵墓,是有著完整的設(shè)計(jì)邏輯,并且隨著好幾座金字塔的迭代的,以及逐漸完備的施工管理,后期金字塔是非常杰出的建筑代表,并作為地球上最高的人造建筑持續(xù)了好幾千年。關(guān)于金字塔是否由奴隸建造還是存有爭(zhēng)議。(圖片來(lái)自 Isabella Jusková @ Unsplash)。
作為工程師,我們一方面關(guān)注軟件產(chǎn)品的能力和行為,這往往是一個(gè)項(xiàng)目的起點(diǎn),另一方面我們需要關(guān)注軟件的架構(gòu)設(shè)計(jì),因?yàn)槲覀兿MO(shè)計(jì)有著彈性、易于維護(hù)、高性能、高可用的系統(tǒng),更希望系統(tǒng)能夠不斷演進(jìn),而不是在未來(lái)被推倒重做。所以,回正我們的視野,當(dāng)我們決心要設(shè)計(jì)一個(gè)好的架構(gòu)時(shí),我們需要明確,架構(gòu)往往決定的是軟件的非功能性需求。這些非功能性需求有:
易于開(kāi)發(fā):我們希望工程師一進(jìn)入團(tuán)隊(duì)就可以立刻開(kāi)始進(jìn)行研發(fā)工作,我們希望代碼易于閱讀與理解,同時(shí)開(kāi)發(fā)環(huán)境足夠簡(jiǎn)單統(tǒng)一,說(shuō)到這里大家可以回想下當(dāng)你進(jìn)入項(xiàng)目時(shí),學(xué)習(xí)上下文的痛苦。當(dāng)我們開(kāi)始采用 docker 輔助開(kāi)發(fā)時(shí),時(shí)任架構(gòu)師提出了一個(gè)要求,只要一行命令就可以使用 docker 啟動(dòng)本地測(cè)試環(huán)境,而且必須所有的微服務(wù)都要做到這一點(diǎn)。痛苦的改造完成后,三年后進(jìn)入項(xiàng)目的同學(xué)只需要安裝好 docker,再在 ternimal 中運(yùn)行一句 ./rundev.sh 就能夠獲取一個(gè)具有完整依賴的本地環(huán)境,提效明顯。
方便部署:如果系統(tǒng)的部署成本很高,那使用價(jià)值就不會(huì)很高了,我們很多企業(yè)都存在那種動(dòng)也不敢動(dòng),改也不敢改,停也不敢停的系統(tǒng),除了祈禱它別掛掉好像沒(méi)有別的辦法,或者很多企業(yè)都采用了 K8s 這種先進(jìn)的編排系統(tǒng),但是在應(yīng)用部署和上線時(shí),還是走的每周四變更的路子?,F(xiàn)代的發(fā)布方式 AB、金絲雀、灰度無(wú)法采用是因?yàn)楦脑斐杀具^(guò)高,或者沒(méi)有足夠的自動(dòng)化測(cè)試來(lái)保證改動(dòng)安全,更別提將發(fā)布做到 CICD 里面了。
易于運(yùn)維:DevOps 的初衷是建立一種縮短運(yùn)維與研發(fā)距離的文化,讓出現(xiàn)問(wèn)題后更容易處理,希望讓大家將視野放在產(chǎn)品上而不是限定自己的工種,這并不是期望運(yùn)維的同學(xué)能夠成為 Java 專(zhuān)家,迅速的進(jìn)行 heap 分析發(fā)現(xiàn)問(wèn)題,我們強(qiáng)調(diào)的是運(yùn)維時(shí)的閉環(huán)能力。在軟件產(chǎn)品層面,我們也希望產(chǎn)品是足夠獨(dú)立的、自治,可以獨(dú)立部署,能夠做到橫向擴(kuò)展,有著完整的可觀測(cè)性,畢竟當(dāng)今的硬件成本很多時(shí)候是遠(yuǎn)遠(yuǎn)小于人力的。
維護(hù)成本:隨著時(shí)間的推移,給軟件增加新功能就會(huì)變的越來(lái)越難,越是運(yùn)行長(zhǎng)久的項(xiàng)目就會(huì)陷入重寫(xiě)還是重構(gòu)的苦惱。往往風(fēng)險(xiǎn)在與,修改代碼會(huì)增加破壞已有功能的風(fēng)險(xiǎn),而且技術(shù)債也會(huì)越來(lái)越多難以償還,即使是重寫(xiě)某些功能和模塊,我們也很難確定是否真的覆蓋到了所有的功能,簡(jiǎn)而言之,dont break anything 的確很難做到。
以及最重要的一點(diǎn),演進(jìn)能力:良好的架構(gòu)設(shè)計(jì)應(yīng)該能讓系統(tǒng)處于易于演進(jìn)的狀態(tài),能夠?qū)崿F(xiàn)給飛馳的汽車(chē)換輪胎的能力,而不會(huì)被框架、底層的某種數(shù)據(jù)庫(kù)、操作系統(tǒng)或者其他東西所綁架,但是這太難以做到了。的確,在項(xiàng)目進(jìn)行技術(shù)選型時(shí),因?yàn)槟撤N數(shù)據(jù)庫(kù)的特性而有傾向,但是在上層設(shè)計(jì)中,我們必須保證不依賴于數(shù)據(jù)庫(kù)的特性,而將使用這些特性的地方放到底層細(xì)節(jié)中。我們也需要考慮,不使用 Spring 提供的 Dependency Injection,我們?cè)撊绾谓M織我們的 beans,也要考慮將來(lái)系統(tǒng)的前端是 web 還是 mobile 還是都要支持
這里引用 Robert C·Martin(Uncle Bob)的原語(yǔ),“軟件產(chǎn)品是有兩方面的價(jià)值,一方面是實(shí)現(xiàn)功能的價(jià)值,另一方面是架構(gòu)的價(jià)值,而架構(gòu)的價(jià)值可能更重要一些,因?yàn)樗碇浖?soft 的特性?!?/p>
本書(shū)例子過(guò)少,而且缺乏現(xiàn)有流行框架的重構(gòu)或者改進(jìn)建議,有點(diǎn)形而上,但是在方法論層面筆者還是認(rèn)為值得一讀。Robert C·Martin 對(duì)數(shù)據(jù)庫(kù)(特指 RDBMS)的態(tài)度很值得討論,首先他認(rèn)為數(shù)據(jù)庫(kù)是一種細(xì)節(jié),在架構(gòu)中應(yīng)該與業(yè)務(wù)解耦,他強(qiáng)調(diào)業(yè)務(wù)代碼與數(shù)據(jù)庫(kù)的無(wú)關(guān)性。同時(shí)在我們的代碼進(jìn)行計(jì)算時(shí),表格往往不是理想的數(shù)據(jù)結(jié)構(gòu),比如有些場(chǎng)景會(huì)使用樹(shù)、DAG 等等??梢曰叵胍幌?,當(dāng)你需要把一個(gè)樹(shù)存入數(shù)據(jù)庫(kù)時(shí),你該如何實(shí)現(xiàn)
微服務(wù)是一種軟件架構(gòu),不要擴(kuò)展它
根據(jù)我們之前的討論,后端系統(tǒng)采用微服務(wù)是不會(huì)影響到其功能上的價(jià)值,本質(zhì)上微服務(wù)化和單體應(yīng)用的差別并不會(huì)表達(dá)在功能上,很多微服務(wù)進(jìn)展不順利的同學(xué)會(huì)經(jīng)常說(shuō)到:這東西用單體寫(xiě)早就完事兒的確是這樣,這側(cè)面也印證了微服務(wù)只是一種軟件架構(gòu),而不是別的神奇的東西,并不是某個(gè)業(yè)務(wù)需求必須要使用微服務(wù)完成,我們看中微服務(wù),也是看中了架構(gòu)方面的優(yōu)勢(shì),即那些非功能性需求。也有人使用 pattern 來(lái)描述它,也有人說(shuō)和 SOA 基本上是一個(gè)東西,只是粒度不同,所以我們一開(kāi)始就別相信這個(gè)世界有靈丹妙藥,也別期望有個(gè)什么技術(shù)能夠瞬間替代 Oracle。
作為開(kāi)發(fā)“企業(yè)級(jí)后端應(yīng)用”的同學(xué),我們經(jīng)常會(huì)面臨很多非業(yè)務(wù)需求上的苦惱:有時(shí)我們需要同時(shí)支持移動(dòng)端、移動(dòng) web、桌面端三種客戶端;有時(shí)候我們需要支持不同的協(xié)議比如 JSON 或 XML;有時(shí)我們又需要使用不同的中間件傳遞消息;或者在研發(fā)時(shí),我們知道有一個(gè)地方寫(xiě)的不好,我們想在未來(lái)補(bǔ)課重構(gòu);我們想嘗試最新的技術(shù)但是代價(jià)過(guò)高;系統(tǒng)無(wú)法擴(kuò)容,或者成本極高;系統(tǒng)過(guò)于復(fù)雜無(wú)法在本地運(yùn)行導(dǎo)致極低的效率……這些苦惱才是采用微服務(wù)的主要驅(qū)動(dòng)力,回到我們對(duì)軟件架構(gòu)的討論之中,我們希望的是通過(guò)足夠松耦合的獨(dú)立服務(wù),來(lái)降低組件之間變化的成本,也就是說(shuō)今天更新發(fā)快遞通知的功能,并不會(huì)影響到用戶查看購(gòu)物車(chē),也不會(huì)讓研發(fā)人員半天改完,再等三天才能上線。
但是世界上沒(méi)有免費(fèi)的午餐,雖然我們知道微服務(wù)有很多很好的特性,比如組件即服務(wù)、松耦合、獨(dú)立部署、面向業(yè)務(wù)、高維護(hù)性、高擴(kuò)展性等等,這里并不想展開(kāi)討論它的好處,我們先考慮投入成本。假設(shè)我們每個(gè)同學(xué)都完整的學(xué)習(xí)了微服務(wù)的所有知識(shí),對(duì)市面上的框架、產(chǎn)品非常熟悉,摩拳擦掌準(zhǔn)備開(kāi)始,在拆解完幾個(gè)服務(wù)后,我們會(huì)發(fā)現(xiàn),沒(méi)有足夠的自動(dòng)化手段,靠手動(dòng)的方式進(jìn)行測(cè)試、編譯、部署、監(jiān)控,這是顯而易見(jiàn)的會(huì)降低體驗(yàn),如果沒(méi)有優(yōu)化好的部署策略,所有的服務(wù)都在某個(gè)發(fā)布日上線,那更是一種災(zāi)難。
隨著規(guī)模的擴(kuò)大,單體應(yīng)用的代碼改動(dòng)成本會(huì)越來(lái)越大。很多時(shí)候我們微服務(wù)的架構(gòu)實(shí)踐是存在誤區(qū)的,我們總認(rèn)為流量經(jīng)過(guò)某個(gè) gateway 后直達(dá)某個(gè)服務(wù),確忽視了服務(wù)之間調(diào)用的場(chǎng)景,理想的微服務(wù)架構(gòu)應(yīng)該是一張網(wǎng),每個(gè)節(jié)點(diǎn)都是獨(dú)立的、自治的服務(wù)。
一些之前使用單體很容易做到的場(chǎng)景,在分布式的環(huán)境下會(huì)更加困難。比如我們可以通過(guò) RDBMS 提供的數(shù)據(jù)庫(kù)事務(wù)來(lái)支撐一致性,但是如果訂單服務(wù)和價(jià)格服務(wù)分離,勢(shì)必要進(jìn)行分布式事務(wù)來(lái)保證一致性(往往是最終一致性),而分布式事務(wù)的成本和難度就不用贅述了。在單體環(huán)境下,我們可以很輕松的使用切面進(jìn)行權(quán)限驗(yàn)證,而在微服務(wù)的場(chǎng)景中,服務(wù)之間相互調(diào)用是難以控制的。
拆分服務(wù)或者服務(wù)邊界劃分是另一件很難做到的事情,最吃香的理論也許是根據(jù) DDD 去進(jìn)行劃分,天然的領(lǐng)域或者子域(domain)貌似都能對(duì)應(yīng)一個(gè)服務(wù),因?yàn)樽銐虻慕缦奚舷挛模╞ounded context)能夠保持服務(wù)的獨(dú)立性,使其細(xì)節(jié)被隱藏在界限之內(nèi),聽(tīng)起來(lái)是個(gè)不錯(cuò)的主意。但是現(xiàn)實(shí)卻十分殘酷,使用 DDD 生搬硬套去進(jìn)行軟件開(kāi)發(fā)的例子不在少數(shù),成功例子也難以復(fù)制。
雖然我在實(shí)踐中也經(jīng)常使用業(yè)務(wù)領(lǐng)域去進(jìn)行服務(wù)劃分,但是我并不認(rèn)為這是 DDD 的做法,沒(méi)有必要規(guī)定有多少個(gè) domain 就有多少服務(wù),也不需要規(guī)定 sub domain 能否獨(dú)立服務(wù)。與其進(jìn)行頂層設(shè)計(jì)一攬子的解決方案,我更相信演進(jìn)的力量,如果你真的需要拆分一個(gè)服務(wù),足夠的基礎(chǔ)設(shè)施與自動(dòng)化工具應(yīng)該允許你低成本的去做,而不是一開(kāi)始就畫(huà)好所有的架構(gòu)圖。這就跟所有的改革一樣,革命派往往不是一步功成,而是逐漸的積累的。所以使用微服務(wù),當(dāng)你能夠負(fù)擔(dān)的起(only you can afford it),也表示你能負(fù)擔(dān)的失敗一樣,技術(shù)世界不存在一蹴而就,all in 非常危險(xiǎn)。
衛(wèi)報(bào)網(wǎng)站(Guardian)的微服務(wù)改造就是一個(gè)很好的例子,網(wǎng)站核心依舊是一個(gè)巨大的單體,但是新功能通過(guò)微服務(wù)實(shí)現(xiàn),這些微服務(wù)調(diào)用單體所提供的 API 來(lái)完成功能。對(duì)于常常出現(xiàn)的市場(chǎng)活動(dòng)(比如某個(gè)體育比賽的專(zhuān)用板塊),這種方式能夠快速實(shí)現(xiàn)活動(dòng)頁(yè)面與功能,完成業(yè)務(wù)需求,并在活動(dòng)結(jié)束后刪除或丟棄。我之前參與項(xiàng)目中,也通過(guò)等量替換與重構(gòu),慢慢絞殺(Strangler Pattern)掉一個(gè)巨大的陳舊的 JBoss 應(yīng)用。
PlayStation 首席設(shè)計(jì)師 Mark Cerny 在今年的 PS5 新主機(jī)的技術(shù)分享中提到,游戲主機(jī)需要平衡好演進(jìn)與革命(balance the evolution and revolution),我們不想丟掉多年來(lái)開(kāi)發(fā)者的積累,在復(fù)用過(guò)去的成功經(jīng)驗(yàn)時(shí),我們也希望大家能夠使用更先進(jìn)的技術(shù)。
人人都愛(ài)恨 Spring Cloud
看起來(lái),在 Java 世界中,Spring Cloud 貌似是微服務(wù)的最優(yōu)解了,甚至在很多同學(xué)的簡(jiǎn)歷上,Spring Cloud 幾乎可以和微服務(wù)劃等號(hào)了,不止一次的有人告訴我說(shuō):公司的技術(shù)棧不是 Java,所以搞不了微服務(wù)很難受,并不是我沒(méi)有學(xué)習(xí)精神和冒險(xiǎn)精神云云。很遺憾,對(duì)于軟件架構(gòu)來(lái)說(shuō),跟可沒(méi)有規(guī)定編程語(yǔ)言,設(shè)計(jì)模式不是也出了很多版本嗎歸根結(jié)底還是 Spring Cloud 的全家桶策略更吸引人,什么事兒都不如加上幾個(gè) jar 就能擁有的神奇次時(shí)代架構(gòu)更有吸引力。
不可否認(rèn),我在學(xué)習(xí) Spring Cloud 的時(shí)候也驚嘆其完整性,幾乎常見(jiàn)的微服務(wù)需求都有足夠完整的解決方案,而大多數(shù)方案是做在應(yīng)用層,具有良好的適配性,比如 eurake 的注冊(cè)發(fā)現(xiàn)、zuul 網(wǎng)關(guān)與路由、config service、hystrix circuit breaker 等等,通過(guò)統(tǒng)一的編程范式(基于 annotation 的注入與配置),足夠豐富的功能選擇(常用功能甚至都有兩種選擇),以及較好的集成方式。前有 Netflix 的成功經(jīng)歷,后隨著微服務(wù)的浪潮,再加上足夠龐大的 Java 社區(qū),可以說(shuō)是王道中的王道。但并非 Spring Cloud 沒(méi)有弱點(diǎn),反倒這些功能設(shè)計(jì)與隨后的容器化浪潮產(chǎn)生了分歧,至今融合 Spring Cloud 與 Kubernetes 都是熱門(mén)話題,這里我們展開(kāi)說(shuō)說(shuō)它的不足或者限制(limitation)。
侵入性與語(yǔ)言綁架
這可能是最大的問(wèn)題,基本只能使用 Java 作為研發(fā)語(yǔ)言,這一點(diǎn)在國(guó)內(nèi)也備受爭(zhēng)議,因?yàn)椴徽撌亲鳛榧軜?gòu)師還是入門(mén)的程序員,都需要嘗試新的技術(shù)棧來(lái)進(jìn)行儲(chǔ)備或是采用新的功能,而且比如使用自制的 client 去實(shí)現(xiàn) ribbon 的負(fù)載均衡也是很難的,但是如果不用 Java,做到這一點(diǎn)也很難,不是說(shuō) Java 語(yǔ)言不夠優(yōu)秀,而是我們對(duì)未來(lái)應(yīng)該有更多的選擇,對(duì)于一個(gè)技術(shù)公司來(lái)說(shuō)編程語(yǔ)言應(yīng)該不會(huì)成為限制,試問(wèn)這個(gè)時(shí)代誰(shuí)不想學(xué)習(xí)一點(diǎn) golang 或者 rust 或者 scala 呢其他服務(wù)比如 SSO、Config Service 也過(guò)于整體,如果想進(jìn)行某項(xiàng)適配,則必須進(jìn)行大量的修改(還好是開(kāi)源的)。我們很擔(dān)心這種情況都會(huì)隨著框架的老去而面臨推到重來(lái)的境界,Ruby on Rails 可能就是前車(chē)之鑒吧。侵入性是另一個(gè)問(wèn)題,還記得我們?cè)谟懻撥浖軜?gòu)時(shí)所提倡的實(shí)踐規(guī)則嗎盡量不要讓頂層設(shè)計(jì)依賴底層的框架或者某種細(xì)節(jié),但是滿屏幕的 annotation 與 jar 的直接引用,無(wú)疑告訴我們想去掉它們還是非常難的。
云原生的融合問(wèn)題
對(duì)于云原生,不論是 CNCF 還是 Pivotal (VMWare)都在強(qiáng)調(diào)容器化、微服務(wù)、面向云環(huán)境等,CNCF 圍繞 Kubernetes 開(kāi)始發(fā)展壯大,也隨著這種先進(jìn)的容器編排技術(shù)的流行人們漸漸發(fā)現(xiàn)它和 Spring Cloud 在功能上還是存在很多重疊,雖然 k8s 與 IaaS 沒(méi)有重疊,但是現(xiàn)在還有多少?gòu)S商再推純 IaaS 呢既然有功能重疊,就有取舍,考慮到 Spring Cloud 的全家桶屬性,這個(gè)分歧處理一直都不能很好的解決。
集中式的資源
不論是 Config 、Eureka 都是聚合的單點(diǎn),及時(shí)它們有集群的方式達(dá)到近乎 100% 的可靠性,但在邏輯架構(gòu)上,所有的微服務(wù)都依賴它們,這些集中式的資源的耦合是非常強(qiáng)的,它們會(huì)一直存在在你的生產(chǎn)環(huán)境之中,直到最后一個(gè)使用它們的系統(tǒng)下線。我們?cè)诩軜?gòu)中需要避免使用共享的實(shí)例與資源,一個(gè)應(yīng)用不會(huì)因?yàn)椴荒軐?xiě)日志而崩潰,也不應(yīng)該因?yàn)楸镜貨](méi)有 eureka 而無(wú)法啟動(dòng)。
畏懼平臺(tái)綁定
誠(chéng)然,在進(jìn)程之內(nèi)解決服務(wù)注冊(cè)發(fā)現(xiàn)、負(fù)載均衡是很好的,它代表了最好了平臺(tái)無(wú)關(guān)性,但平臺(tái)的其他能力也很難享受的到了。綁定 k8s 貌似是個(gè)更好的選擇,因?yàn)橄鄬?duì)于 Spring Cloud 它更靈活,也能做到不會(huì)被基礎(chǔ)的云平臺(tái)綁定,但也更難以掌握與運(yùn)維。當(dāng)然我也不是認(rèn)為 K8s 必須作為微服務(wù)的選擇,作為容器的編排平臺(tái),它可以做更多的事情(比如跑數(shù)據(jù)庫(kù)、中間件等),運(yùn)行微服務(wù)應(yīng)用只是其中之一。
方法論的落地能力
2020年已經(jīng)過(guò)了一半,從技術(shù)上來(lái)說(shuō),Serverless 已經(jīng)進(jìn)入成熟期,Kubernetes 也更加成熟,已經(jīng)成為事實(shí)的標(biāo)準(zhǔn)。但是很多時(shí)候我們的方法論與架構(gòu)設(shè)計(jì)是跟不上的技術(shù)發(fā)展的,很多同學(xué)可能還在經(jīng)歷每周的發(fā)布日,很多同學(xué)還沒(méi)辦法改進(jìn)團(tuán)隊(duì)內(nèi)老舊的技術(shù),很多同學(xué)的 Jenkins 還是停留在打包的階段,很多同學(xué)機(jī)器上還是沒(méi)有安裝 docker,很多時(shí)候并不是框架或者平臺(tái)的問(wèn)題,而是方法論還停留在過(guò)去。
保持演進(jìn)
應(yīng)用程序也應(yīng)該踐行開(kāi)閉原則,對(duì)擴(kuò)展開(kāi)放使得我們?cè)谖磥?lái)有更多的選擇。微服務(wù)是一個(gè)很好的機(jī)會(huì)能讓我們真正的演進(jìn)架構(gòu)而不需要付出過(guò)多的代價(jià),當(dāng)我們需要組件化系統(tǒng)時(shí),組件的關(guān)鍵特性正是可獨(dú)立替換或升級(jí),我們可以不影響其他部分去進(jìn)行替換和重構(gòu),這樣的成本是顯然低于拋棄舊的巨型框架而重寫(xiě)的。有著正確的態(tài)度和工具,我們可以更快、更頻繁的控制變更,我們可以激進(jìn)的選擇新的技術(shù)棧,也可以合并兩個(gè)耦合過(guò)緊的服務(wù),隨著服務(wù)的不斷聚合、抽出,你會(huì)發(fā)現(xiàn)系統(tǒng)的邏輯架構(gòu)會(huì)越來(lái)越清楚,再進(jìn)行修改就會(huì)信心倍增了。我們可以針對(duì)每個(gè)服務(wù)使用不同的存儲(chǔ)技術(shù),我們可以使用 OSS 處理文件,而不是繼續(xù)往 Oracle 里面塞圖片和視頻。
Istio 的解法與問(wèn)題,以及 Mesh 還缺少什么
這個(gè)開(kāi)幕雷擊雖然槽點(diǎn)滿滿,但并沒(méi)有降低社區(qū)對(duì) Istio 的信心,反倒是漸漸發(fā)現(xiàn)這次的大改動(dòng)使 Istio 變得有點(diǎn)好用了,可以在生產(chǎn)中采用而不需要付出太多代價(jià)了。當(dāng)然,漂亮話永遠(yuǎn)好說(shuō)。
2017 年的時(shí)候 Service Mesh 還是一個(gè)襁褓中的概念,現(xiàn)在已經(jīng)成為了微服務(wù)領(lǐng)域的未來(lái)之選,但遺憾的是目前只有 Istio 足夠成熟能代表這項(xiàng)技術(shù),當(dāng)然我也有幸實(shí)踐過(guò)類(lèi)似的 Sidecar 來(lái)進(jìn)行反向代理、日志收集、性能監(jiān)控、健康檢查等功能,但是距離 Mesh 的愿景還是有大的差距。
今天并不想展開(kāi) Service Mesh 或者 Istio 的優(yōu)勢(shì),進(jìn)程之外的解決方案能夠確保系統(tǒng)的靈活性,而流量控制、服務(wù)治理、端對(duì)端的傳輸安全、限流、發(fā)現(xiàn)注冊(cè)等等,我們希望工程師能夠聚焦業(yè)務(wù),實(shí)現(xiàn)架構(gòu)的靈活性,聚焦真正的價(jià)值,而剩下的進(jìn)行配置就好。所以我想這也是 Serverless 被無(wú)限看好的原因,既然我們想 delegate 對(duì)基礎(chǔ)設(shè)施的控制,那為什么還需要關(guān)心容器呢Istio + k8s 的方案已經(jīng)足夠好,至少我們團(tuán)隊(duì)正在認(rèn)真學(xué)習(xí),在向客戶提供最佳實(shí)踐之前,我們依舊有很多問(wèn)題需要解決,下面列出一些代表性的:
彈性與自恢復(fù)問(wèn)題
使用系統(tǒng)度量、參數(shù)等觸發(fā)彈性伸縮是常見(jiàn)的需求,這里我們是使用云監(jiān)控還是自己搭一套我一直傾向數(shù)據(jù)與用途解耦,使用 pub sub 模式解決問(wèn)題,比如 CPU 過(guò)高可能會(huì)觸發(fā)多個(gè)行為:觸發(fā)警報(bào),觸發(fā)彈性規(guī)則,展示在 dashboard 上。我們可以增加 pod 來(lái)分擔(dān)服務(wù)的壓力,或者因?yàn)槟硞€(gè) pod 異常退出后,啟動(dòng)新的 pod 來(lái)完成自恢復(fù),這系列動(dòng)作也是需要我們自己解決的。
監(jiān)控與可觀測(cè)性
日志、警報(bào)等可觀測(cè)性的問(wèn)題,這一方面的實(shí)踐較多,唯一比較擔(dān)心的是 ARMS 或者 Newrelic 這種 APM 功能目前沒(méi)在目標(biāo)平臺(tái)上實(shí)踐過(guò),我們希望能夠清晰的看到每個(gè)服務(wù)的實(shí)時(shí)性能,目前這一部分還缺乏考慮與設(shè)計(jì)。
限流與降級(jí)的實(shí)踐
Istio 的流量控制能力是非常強(qiáng)大的,如何對(duì)服務(wù)采取降級(jí)、限流這種常見(jiàn)的治理操作,也是需要總結(jié)出實(shí)踐經(jīng)驗(yàn)的。避免串流錯(cuò)誤(cascade failure)在微服務(wù)領(lǐng)域也很常見(jiàn),也需要避免故障蔓延。
多種自動(dòng)化部署
藍(lán)綠、灰度、金絲雀,這些多樣的部署方式也需要落地,我們可能會(huì)寫(xiě)一些 deployment util 之類(lèi)的小腳本,部署的方式需要和 CICD 打通。一個(gè)部署工具,一個(gè)配置文件,一個(gè) CICD 組成未來(lái)單個(gè)應(yīng)用的部署方式。
ABAC 與 OPA
基于屬性的權(quán)限控制以及 OPA 的可定制性我們是非??春玫?,而且 sidecar 可以在進(jìn)程之外解決權(quán)限驗(yàn)證問(wèn)題,的確值得嘗試,剛好也學(xué)習(xí)下 golang 用于定制 OPA。
Saga 與補(bǔ)償事件
分布式事務(wù)是微服務(wù)實(shí)踐中的大坑,我曾經(jīng)也寫(xiě)過(guò)類(lèi)似的文章,項(xiàng)目經(jīng)驗(yàn)中更多的是將事務(wù)放在單一的服務(wù)內(nèi),再加上我自己也沒(méi)機(jī)會(huì)寫(xiě)過(guò)真正的網(wǎng)店系統(tǒng)。補(bǔ)償事件也是常用的最終一致性方案,總之放在一起驗(yàn)證。
高可用和混沌工程
基于 K8s 實(shí)現(xiàn)應(yīng)用的高可用應(yīng)該不難,容器的天生優(yōu)勢(shì)就是易于啟動(dòng)與管理,如果隨機(jī)殺掉 pod 不會(huì)影響系統(tǒng)可用性,這就算是實(shí)現(xiàn)了類(lèi)似于 SLB + ECS + ASG 的能力,真正危險(xiǎn)的是其他 非業(yè)務(wù)型 pod,比如 istio 的各種 supervisor。
實(shí)踐微服務(wù),作為架構(gòu)師所考慮的東西遠(yuǎn)遠(yuǎn)大于只是實(shí)現(xiàn)業(yè)務(wù),但是一旦鋪平道路,下來(lái)的研發(fā)與迭代將會(huì)更加順利。
特別聲明:以上文章內(nèi)容僅代表作者本人觀點(diǎn),不代表ESG跨境電商觀點(diǎn)或立場(chǎng)。如有關(guān)于作品內(nèi)容、版權(quán)或其它問(wèn)題請(qǐng)于作品發(fā)表后的30日內(nèi)與ESG跨境電商聯(lián)系。
二維碼加載中...
使用微信掃一掃登錄
使用賬號(hào)密碼登錄
平臺(tái)顧問(wèn)
微信掃一掃
馬上聯(lián)系在線顧問(wèn)
小程序
ESG跨境小程序
手機(jī)入駐更便捷
返回頂部