實(shí)踐出真知
在上面的電商案例中,我們提到了服務(wù)無(wú)狀態(tài)化,之所以期望服務(wù)無(wú)狀態(tài)化,是因?yàn)闊o(wú)狀態(tài)應(yīng)用可以做到快速的擴(kuò)縮容,可以應(yīng)對(duì)井噴流量,可以最大效率的利用計(jì)算資源。我們經(jīng)常聽(tīng)到,以無(wú)狀態(tài)為榮,以有狀態(tài)為恥,說(shuō)的就是對(duì)于一個(gè)服務(wù)要盡量無(wú)狀態(tài)化它,比如用戶 session 管理,以前我們?cè)跇I(yè)務(wù)邏輯模塊進(jìn)行管理,導(dǎo)致這些模塊不能按照無(wú)狀態(tài)方式任意伸縮。我們可以把這些 session 的管理抽取出來(lái)放到一個(gè)高可用或分布式的緩存中管理,業(yè)務(wù)模塊通過(guò)調(diào)用API的方式去獲取 session,這樣就實(shí)現(xiàn)了這些模塊的無(wú)狀態(tài)化。
但這并不意味著所有服務(wù)都做到無(wú)狀態(tài)才是最好的,開(kāi)發(fā)者要細(xì)細(xì)思考自己的業(yè)務(wù)模型并進(jìn)行服務(wù)拆分,不要為了無(wú)狀態(tài)而無(wú)狀態(tài),因?yàn)榭偸菚?huì)存在有狀態(tài)服務(wù)的。
第二階段進(jìn)階—— 改造遺留應(yīng)用
如果我們經(jīng)過(guò)認(rèn)真思考后仍決定對(duì)遺留應(yīng)用進(jìn)行微服務(wù)化,比如需要新增功能、快速迭代現(xiàn)有功能等,那么最好遵循一些最佳實(shí)踐經(jīng)驗(yàn)。顯然,另起爐灶開(kāi)發(fā)一套新的系統(tǒng)不太現(xiàn)實(shí),失敗的概率非常高。
第一點(diǎn)注意:新增功能點(diǎn)不能再在原有單體應(yīng)用基礎(chǔ)上開(kāi)發(fā),而是需要按照微服務(wù)方式開(kāi)發(fā),但由于這個(gè)微服務(wù)是隸屬于原來(lái)單體應(yīng)用的一部分功能,所以通常情況需要訪問(wèn)單體應(yīng)用的數(shù)據(jù),這個(gè)時(shí)候需要通過(guò)API的方式訪問(wèn),以防止二者之間發(fā)生緊耦合。對(duì)于單體部分來(lái)說(shuō),無(wú)論是采用 Facade,還是 Adapter 或 Translator 模式提供 API,都是為新增的微服務(wù)模塊提供松耦合的訪問(wèn)方式。
第二點(diǎn)注意:對(duì)于已有的單體部分也可以逐步微服務(wù)化,可選擇經(jīng)常變化、需要快速迭代滿足用戶需求的部分著手進(jìn)行改造。經(jīng)過(guò)幾輪改造后要么整體替換掉原單體應(yīng)用,要么剩下的是穩(wěn)定不變的單體部分,周圍就都是改造過(guò)的微服務(wù)混合架構(gòu)了。
第三階段收放自如——Service Mesh
Service mesh 是微服務(wù)架構(gòu)的一部分,它本質(zhì)上是一個(gè)分布式計(jì)算中間件,通過(guò)攔截流量和安置策略來(lái)管理和優(yōu)化服務(wù)之間的通信,使得服務(wù)變得更加健壯和安全。通常會(huì)提供微服務(wù)之間認(rèn)證、鑒權(quán)、加密、服務(wù)發(fā)現(xiàn)、請(qǐng)求路由、負(fù)載均衡、服務(wù)自愈等功能。
部署微服務(wù)應(yīng)用,service mesh 是必不可少的部分。這是因?yàn)槲⒎?wù)應(yīng)用是一個(gè)分布式的應(yīng)用,因此相對(duì)于單體應(yīng)用來(lái)說(shuō)在穩(wěn)定性、可管理性等方面都有很大難度,需要有 service mesh來(lái)管理幫助服務(wù)變得更加健壯和安全。
因此,Service mesh 選型也是比較重要的,經(jīng)常聽(tīng)到有人糾結(jié)是選擇?Istio 還是 Spring Cloud 等。我們認(rèn)為?Istio 是 service mesh 的發(fā)展方向,從架構(gòu)來(lái)說(shuō),它解耦了控制平面和數(shù)據(jù)平面,使得開(kāi)發(fā)者可以專注于應(yīng)用業(yè)務(wù)邏輯的開(kāi)發(fā),而復(fù)雜的分布式應(yīng)用服務(wù)之間的通信交給 service mesh 來(lái)控制。Spring Cloud 在架構(gòu)設(shè)計(jì)理念上是落后的,試想一下,開(kāi)發(fā)者在開(kāi)發(fā)微服務(wù)的時(shí)候還要思考如何在代碼中實(shí)現(xiàn)熔斷、灰度發(fā)布、負(fù)載均衡等問(wèn)題,負(fù)擔(dān)是非常重的。更重要的是 Spring Cloud 類型的 service mesh 只支持 Java 語(yǔ)言,完全違背微服務(wù)可以任選語(yǔ)言開(kāi)發(fā)的主張,而且有 vendor lock-in 嫌疑。
Istio 身上鮮明的標(biāo)簽很多:天然適合 Kubernetes 平臺(tái),不侵入代碼,無(wú)語(yǔ)言綁定,但不得不承認(rèn),Istio 還在發(fā)展過(guò)程當(dāng)中,目前也有一些問(wèn)題亟待解決:
雖然?Istio 存在上述問(wèn)題,但我們更應(yīng)看到其社區(qū)正在飛速增長(zhǎng),就好比一兩年前 k8s、docker swarm 和 Mesos 之爭(zhēng)一樣,那個(gè)時(shí)候 k8s 強(qiáng)大的生態(tài)活躍度為它最終勝利打下了良好的基礎(chǔ),我們認(rèn)為?Istio 就是在 service mesh 領(lǐng)域的 k8s,未來(lái)很有可能會(huì)贏得這個(gè)領(lǐng)域的主導(dǎo)地位。當(dāng)一個(gè)應(yīng)用的微服務(wù)越來(lái)越多的時(shí)候,service mesh 變得非常重要,而且目光看得更遠(yuǎn)一些,隨著 FaaS 步入業(yè)務(wù)開(kāi)發(fā)者的視野,大家越來(lái)越享受這種便捷、靈活的開(kāi)發(fā)方式,這意味著以服務(wù)視角的開(kāi)發(fā)模式會(huì)越來(lái)越流行,因此 service mesh 框架會(huì)變得越來(lái)越重要。
綜上所述,通過(guò)?Istio 構(gòu)建微服務(wù)治理屏幕,學(xué)習(xí)曲線起點(diǎn)比較高,運(yùn)維也非常麻煩,運(yùn)維人員關(guān)注的是功能的輸出,比如熔斷、限流、灰度發(fā)布等,但?Istio 要求他們先要部署組件,編輯 yaml,了解各種抽象的參數(shù),這就好比在看 3D 電影前,讓觀眾自己先要組裝 3D 眼鏡一樣。因此,微服務(wù)進(jìn)階之路道阻且長(zhǎng),企業(yè)需要一個(gè)平臺(tái)級(jí)商業(yè)產(chǎn)品,可以從業(yè)務(wù)視角來(lái)管理微服務(wù)的可視化工具或者平臺(tái),降低用戶的學(xué)習(xí)和運(yùn)維成本,提高用戶的業(yè)務(wù)價(jià)值輸出能力,幫助用戶重塑數(shù)字化時(shí)代核心競(jìng)爭(zhēng)力。