四步輕松玩轉(zhuǎn)微服務(wù)敏捷開發(fā)
01 微服務(wù)敏捷開發(fā)不簡單
1 安得環(huán)境千萬套,大庇開發(fā)小哥俱歡笑
微服務(wù)給大家?guī)砹嗣艚蓍_發(fā)的特性,基于敏捷開發(fā)帶來的便利,讓我們可以在同一個(gè)時(shí)間內(nèi)多個(gè)迭代/feature 并行開發(fā)。但微服務(wù)架構(gòu)本身也給開發(fā)環(huán)境帶來了一定的復(fù)雜性:每個(gè) feature 的修改點(diǎn)都可能會(huì)被分散在多個(gè)應(yīng)用中,需要多個(gè)應(yīng)用互相配合才能完成整體的邏輯。這些應(yīng)用既需要互相配合好,又不能讓他們互相影響,故敏捷開發(fā)有時(shí)候也不是那么容易。
相信實(shí)踐過微服務(wù)敏捷開發(fā)的同學(xué)曾經(jīng)都遇到過以下情況:
1.開發(fā)接口時(shí),應(yīng)用無法獨(dú)立地聯(lián)調(diào)測試,需要依賴于下游的返回,所以一般都需要一個(gè)完整的開發(fā)環(huán)境,這個(gè)環(huán)境需要包含所有的其他應(yīng)用。
2.A 同學(xué)辛辛苦苦,終于開發(fā)好了一個(gè)接口,但是部署到開發(fā)環(huán)境后,發(fā)現(xiàn)返回值一直是錯(cuò)的,就是不符合預(yù)期,百思不得其解。最終根據(jù)日志、arthas 層層跟蹤下去,發(fā)現(xiàn)原來是另一個(gè)同事更新了下游應(yīng)用的代碼,導(dǎo)致原有邏輯發(fā)生了變更。
3.A 同學(xué)準(zhǔn)備開始聯(lián)調(diào)測試了,這時(shí)候他要找到開發(fā) B 和 C 吼一嗓子確認(rèn):“我要開始測試了哈兄弟們,你們都別動(dòng)環(huán)境,不要重啟和 debug 哈”。B 同學(xué) 和 C 同學(xué)一臉懵逼:“我自己這還有個(gè)邏輯沒理清楚呢,剛改完代碼準(zhǔn)備測一發(fā),你這一測試聯(lián)調(diào)我就不能動(dòng)環(huán)境了,我這功能得等到什么時(shí)候才能開發(fā)好”。
4.排查問題好麻煩啊,要不直接 debug 一下吧,這 IDEA 遠(yuǎn)程 debug 剛連上去呢,立馬就傳來了同事的聲音:“誰 XX 又在瞎動(dòng)環(huán)境啊,怎么剛剛還能跑的接口現(xiàn)在就出錯(cuò)了”。
以上這些問題顯然會(huì)影響項(xiàng)目的進(jìn)度,非常容易造成項(xiàng)目延期。對于此刻的開發(fā)小哥哥而言,擁有一套屬于自己的獨(dú)立環(huán)境,帶來的幸福感也許比有一套屬于自己的小房子還大。
2 流量閉環(huán)是微服務(wù)敏捷開發(fā)的基礎(chǔ)
上文中提到的問題,其實(shí)都是因?yàn)闆]有在開發(fā)環(huán)境中,精準(zhǔn)地控制流量在 feature 環(huán)境內(nèi)流轉(zhuǎn)。
為什么精準(zhǔn)地控制流量如此重要?舉個(gè)最簡單的微服務(wù)架構(gòu)圖來說明,這里假設(shè)應(yīng)用的調(diào)用鏈路為 A ---> B ---> C ---> D ,現(xiàn)在同時(shí)開發(fā)兩個(gè) feature, feature1 和 feature2 。feature1 需要修改 A 和 C 的代碼, feature2 需要修改 B、C 和 D 的代碼。
為了方便表述,我們用 A、B、C、D 來代指 A、B、C、D 的線上穩(wěn)定版本,也叫做基線版本;A1、C1 來代指 feature1 環(huán)境中的 A 和 C ;B2、C2、D2 來來代指 feature2 環(huán)境中 B、C、D。
那么開發(fā)測試 feature1 的同學(xué)會(huì)要求他的請求,準(zhǔn)確地在 A1 ---> B ---> C1 ---> D 中流轉(zhuǎn)。為什么一定要這樣,我們來簡單分析一下:
1.如果流量走到 A 或者 C 的基線環(huán)境,因?yàn)樗麄兌紱]有包含 feature1 相關(guān)的代碼,所以肯定是無法正常測試和聯(lián)調(diào) feature1 對應(yīng)的功能。
2.如果流量走到 B2、D2 環(huán)境,大多數(shù)情況下是可以正常工作的,因?yàn)檎G闆r下 B2 和 D2 中的修改是不會(huì)影響 feature1 的。但是因?yàn)?feature1 和 feature2 可能是由不同的同學(xué)開發(fā)的,或者有不同的開發(fā)排期和節(jié)奏,他們有自己的開發(fā)、重啟、debug 節(jié)奏,所以大概率還是會(huì)出現(xiàn)上文中提到的場景。
綜上所述,讓流量在 feature 環(huán)境內(nèi)流轉(zhuǎn)非常重要,是微服務(wù)敏捷開發(fā)的基礎(chǔ)。
如何準(zhǔn)確地讓請求在 feature 環(huán)境內(nèi)流轉(zhuǎn)呢?最簡單的辦法是每個(gè)迭代/feature 的都享有一套獨(dú)立的完整環(huán)境,這套獨(dú)立的環(huán)境包含了整個(gè)微服務(wù)應(yīng)用集所有的應(yīng)用,包含注冊中心和接入層,這樣就能確保流量在 feature 環(huán)境里閉環(huán),不用擔(dān)心應(yīng)用之間互相影響。
這個(gè)解決方案雖然簡單,但是問題也很顯而易見,成本比較大。我們假設(shè)微服務(wù)應(yīng)用有10 個(gè),每個(gè)應(yīng)用只部署一臺(tái),以 java 為例,部署一個(gè) java 應(yīng)用按 2C4G 的 共享標(biāo)準(zhǔn)型 ECS 進(jìn)行計(jì)算,維護(hù)一套環(huán)境一年的成本是 10 × 140 × 12 = 16800 元,如果同時(shí)有 4 套環(huán)境,即只支持兩個(gè)迭代并行開發(fā),每個(gè)迭代只有 2 個(gè) feature,這樣一年的成本就是 67200 元,而且我們可以發(fā)現(xiàn),這里面計(jì)算公式使用的是乘法,當(dāng)應(yīng)用增加和環(huán)境增加時(shí),成本的增加是成倍的。
注意,這里只是單純地計(jì)算了應(yīng)用使用的 ECS 的成本,其他周邊的配套設(shè)施我們還沒有計(jì)算,因?yàn)槲覀兊拈_發(fā)、聯(lián)調(diào)、測試是需要確保端到端的全流程都是足夠順利的,那這里就還會(huì)涉及到 域名/SLB/網(wǎng)關(guān)/注冊中心這些資源,這些資源一般比較固定,不會(huì)需要進(jìn)行大的修改,但是在多套環(huán)境的方案下這些資源也需要維護(hù)多套,成本還會(huì)進(jìn)一步上升。
那么,有沒有一個(gè)比較優(yōu)雅地方式,既能享受到微服務(wù)架構(gòu)帶來的敏捷開發(fā)的便利,又不會(huì)給日常開發(fā)環(huán)境的搭建帶來很大的成本呢?基于 MSE(微服務(wù)引擎 MSE,以下簡稱 MSE)標(biāo)簽路由功能使用開發(fā)環(huán)境隔離方案是您的不二之選。
3 如何低成本玩轉(zhuǎn)敏捷開發(fā)
什么是 MSE 開發(fā)環(huán)境隔離,簡單地說就是將 feature 環(huán)境的隔離方式從簡單的物理隔離轉(zhuǎn)為邏輯隔離。借助于 MSE 提供的邏輯隔離,您只需要維護(hù)一套完整的基線環(huán)境,在增加 feature 環(huán)境時(shí),只需要單獨(dú)部署這個(gè) feature 所涉及到改動(dòng)的應(yīng)用即可,而不需要在每個(gè) feature 環(huán)境都部署整套的微服務(wù)應(yīng)用及其配套設(shè)施。
我們稱這唯一的一套完整的環(huán)境為基線環(huán)境?;€環(huán)境包含了所有微服務(wù)應(yīng)用,也包含了服務(wù)注冊中心、域名、SLB、網(wǎng)關(guān) 等其他設(shè)施,而 feature 環(huán)境中只包含了這個(gè) feature 中需要修改的應(yīng)用。這樣維護(hù) n 套 feature 環(huán)境的成本,就變成了加法,而不是原來的乘法,由 n × m 變成了 n + m。差不多相當(dāng)于零成本增加 feature 環(huán)境,這樣我們就可以放心地?cái)U(kuò)容出多套 feature 環(huán)境,每個(gè)開發(fā)小哥哥都可以輕松擁有屬于自己的獨(dú)立環(huán)境,盡情地享受微服務(wù)敏捷開發(fā)。
從上圖中我們可以看到,feature1 對應(yīng)的流量,在發(fā)現(xiàn) feature1 中存在 A1 應(yīng)用時(shí),一定會(huì)去往 A1 節(jié)點(diǎn),A1在調(diào)用B的時(shí)候發(fā)現(xiàn) feature1 環(huán)境中不存在 B1 ,則會(huì)將請求發(fā)到 基線版本的 B 中;B在調(diào)用C時(shí),發(fā)現(xiàn) feature1 環(huán)境存在 C1 應(yīng)用,又會(huì)返回到 feature1 環(huán)境中,依次類推,確保了流量會(huì)在 feature1 環(huán)境中閉環(huán)。
而且,在這個(gè)過程中,您不需要修改任何代碼和配置,直接接入 MSE 微服務(wù)治理即可使用,不會(huì)給您增加任何開發(fā)成本。
02 如何使用 MSE 開發(fā)環(huán)境隔離
1 開通 MSE 微服務(wù)治理專業(yè)版
登錄 MSE治理中心控制臺(tái),如果您尚未開通 MSE 微服務(wù)治理,請根據(jù)提示開通專業(yè)版。如果您已經(jīng)開通了MSE 微服務(wù)治理基礎(chǔ)版,請根據(jù)概覽頁中右側(cè)的提示,升級到 專業(yè)版。
2 部署基線環(huán)境/基線環(huán)境接入
首先需要將基線環(huán)境的所有應(yīng)用接入到 MSE 中,接入方式與您開發(fā)環(huán)境中應(yīng)用部署方式有關(guān)。這里我們拿兩個(gè)典型的場景作為例子進(jìn)行說明。更多接入場景請參考 MSE 幫助文檔 MSE 微服務(wù)治理快速入門。
-
阿里云容器服務(wù) ACK
若您的開發(fā)環(huán)境部署在 阿里云容器服務(wù)的 ACK 中,將基線環(huán)境接入 MSE 的流程如下:
1.在 ACK 中安裝 MSE 治理中心組件
- 登錄容器服務(wù)控制臺(tái)。
- 在左側(cè)導(dǎo)航欄單擊市場 > 應(yīng)用目錄。
- 在應(yīng)用目錄頁面搜索并單擊 ack-mse-pilot。
- 在 ack-mse-pilot 頁面右側(cè)集群列表中選擇集群,然后單擊創(chuàng)建。
創(chuàng)建成功后,會(huì)自動(dòng)跳轉(zhuǎn)到目標(biāo)集群的發(fā)布頁面,檢查安裝結(jié)果。如果出現(xiàn)以下頁面,展示相關(guān)資源,則說明安裝成功。
2.為 ACK 命名空間中的應(yīng)用開啟 MSE 微服務(wù)治理
3.完成上述步驟后,重啟/部署基線版本的應(yīng)用,您的基線環(huán)境就已經(jīng)接入完成。
-
ECS/虛擬機(jī)
若您的應(yīng)用是通過 ECS 或者 虛擬機(jī)的方式部署的,請您打開 MSE微服務(wù)治理控制臺(tái)中的應(yīng)用列表-接入方式-ECS 集群,根據(jù)指南里面的提示進(jìn)行操作。
1.通過Shell腳本方式下載Agent 復(fù)制以下命令行并在待治理應(yīng)用所處的系統(tǒng)中運(yùn)行。
wget -O- http://mse-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/install.sh | sh # 此命令具體內(nèi)容會(huì)隨著您控制臺(tái)中的選擇的 Region 而變化,請注意在控制臺(tái)中選擇機(jī)器所在的 Region # 若您的機(jī)器不在阿里云環(huán)境中,請選擇 杭州 Region。
2.接入 MSE Agent
a. 將MseAgent.zip中的所有文件解壓到任意目錄中。
unzip MseAgent -d /{user.workspace}/ # 說明 “{user.workspace}”是示例路徑,請根據(jù)具體環(huán)境替換為正確的路徑。
b. 在應(yīng)用啟動(dòng)參數(shù)上添加AppName以及LicenseKey參數(shù)。
java -javaagent:/{user.workspace}/MseAgent/mse-bootstrap-1.7.0-SNAPSHOT.jar
-Dmse.licenseKey=<yourLicenseKey>
-Dmse.appName=<yourAppName>
-Dmse.enable=true -jar A.jar #系統(tǒng)將為您自動(dòng)生成的 <yourLicenseKey> ,在上文中提到的 ECS接入指南 界面查看,請勿泄露。 #<yourAppName> 為應(yīng)用名稱,同一應(yīng)用在后續(xù)的 feature 環(huán)境接入需要保持應(yīng)用名稱一致
注意:各個(gè) Region 的 LicenseKey 值可能不一致,請注意選擇正確的 Region,若您的機(jī)器不在阿里云環(huán)境中,請選擇 杭州 Region。
-
驗(yàn)證環(huán)境接入成功
完成上述步驟后,您的基線環(huán)境就已經(jīng)部署好了。您可以在 MSE 控制臺(tái)中找到對應(yīng)的 Region 查看應(yīng)用列表,以及應(yīng)用詳情頁的節(jié)點(diǎn)情況。
3 將應(yīng)用接入 feature 環(huán)境
將應(yīng)用接入 feature 環(huán)境的方式和第二步中的方式基本相同,只不過這里需要額外給應(yīng)用打上一個(gè)標(biāo)簽,將這個(gè)應(yīng)用標(biāo)記為屬于 feature 環(huán)境。
同樣的,接入 feature 環(huán)境的方式也和應(yīng)用的部署形態(tài)相關(guān),這里同樣分別以 K8s 和 ECS 方式舉例,如何將 A 應(yīng)用接入到 feature1 環(huán)境。
-
K8s 部署方式
如果您的應(yīng)用是通過 K8s 方式部署,則應(yīng)用在接入 feature1 環(huán)境時(shí)需要在 deployment 中的 spec > template > metadata 下的 annotations 增加如下配置:
spec:
template:
metadata:
annotations:
alicloud.service.tag: feature1
-
ECS/虛擬機(jī)
如果您的應(yīng)用是通過 ECS/虛擬機(jī)的方式部署,則應(yīng)用在接入 feature1 環(huán)境時(shí)需要額外配置 JVM 系統(tǒng)屬性(SystemProperty) ,增加的方式為在 Java 啟動(dòng)命令中增加 `-Dalicloud.service.tag=feature1`,完整的啟動(dòng)命令如下:
java -javaagent:/{user.workspace}/MseAgent/mse-bootstrap-1.7.0-SNAPSHOT.jar -Dmse.licenseKey=<yourLicenseKey> -Dmse.appName=<yourAppName> -Dmse.enable=true -Dalicloud.service.tag=feature1 -jar A.jar
-
驗(yàn)證環(huán)境接入成功
完成上述操作后,登錄 MSE 控制臺(tái),找到剛才啟動(dòng)的應(yīng)用,在詳情頁面查看實(shí)例詳情,可以確認(rèn)節(jié)點(diǎn)的 ip 和標(biāo)簽是否符合預(yù)期。
4 輕松開始聯(lián)調(diào)和測試
假設(shè)我們發(fā)往網(wǎng)關(guān)的請求是 http 請求,希望這個(gè)請求再 feature1 中完成閉環(huán),只需要在請求的 header 中添加 x-mse-tag=feature1 即可,流量會(huì)自動(dòng)在 feature1 環(huán)境內(nèi)完成閉環(huán)。注意這里的 key 為 x-mse-tag 為固定值,feature1 則需要和環(huán)境的標(biāo)簽(即上文中配置的 alicloud.service.tag)保持一致。
如果您的請求來源為 Dubbo,則需要在 RpcContext 中增加 Attachment ,內(nèi)容也是 x-mse-tag=feature1。
特別地,如果您的網(wǎng)關(guān)應(yīng)用不屬于 Java 體系,則需要在網(wǎng)關(guān)層配置一下規(guī)則,目前已經(jīng)支持 MSE云原生網(wǎng)關(guān),Nginx,K8s Ingress 等,詳細(xì)的接入方式可以參考 MSE 全鏈路灰度配置 。
03 更進(jìn)一步 IDEA 接入 feature 環(huán)境
上文中提到過,開發(fā)聯(lián)調(diào)過程中,將應(yīng)用部署到聯(lián)調(diào)環(huán)境也是需要成本的,能不能直接在 IDEA 里面把正在開發(fā)的微服務(wù)跑起來呢?這樣豈不是就可以直接愉快地快速部署和 debug 了?當(dāng)然可以!而且操作起來還非常簡單!
將 IDEA 啟動(dòng)的應(yīng)用直接接入到 feature 環(huán)境中也不復(fù)雜,只需要簡單幾步即可實(shí)現(xiàn)。
注意:使用此特性的前提條件為,您本機(jī)的網(wǎng)絡(luò)與開發(fā)環(huán)境其他應(yīng)用能夠正常通訊。
1 安裝 CloudToolkit 插件
安裝最新版本的 Cloud Toolkit,安裝詳情請參考官網(wǎng):https://www.aliyun.com/product/cloudtoolkit
2 配置 MSE 參數(shù)
點(diǎn)擊 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Microservice 下的 MSE ,點(diǎn)擊 開啟微服務(wù)治理,并安裝下圖的方式進(jìn)行配置即可。
對以下幾個(gè)參數(shù)做一下說明:
LicenseKey
您阿里云賬號(hào)對應(yīng)的 MSE 產(chǎn)品的 LicenseKey ,請?jiān)?https://mse.console.aliyun.com/#/msc/app/accessType 中的選擇 ECS 集群,在 安裝 MSE Agent 章節(jié)找到 LicenseKey 的值。
注意:請您做好 LicenseKey 的保密工作。
注意:各個(gè) Region 的 LicenseKey 值可能不一致,請選擇對應(yīng)的 Region,并和基線環(huán)境接入的 Region 保持一致。
App Name
應(yīng)用在接入 MSE 時(shí)所使用的應(yīng)用名,請根據(jù)實(shí)際業(yè)務(wù)情況進(jìn)行配置,注意這個(gè)值需要和本次所啟動(dòng)的應(yīng)用保持一致。
Tag
此應(yīng)用所屬的環(huán)境 Tag,基線不用填,其他請根據(jù)實(shí)際業(yè)務(wù)情況進(jìn)行填寫。如果此應(yīng)用屬于 feature1 環(huán)境,請?zhí)顚?feature1。
Agent 地址
選擇自己應(yīng)用所在的地域,需要和 LienseKey 所在的地域、以及基線環(huán)境接入的地域 都保持一致。
開啟 RPC 灰度 ?
支持對 Spring Cloud 和 Dubbo 近5年內(nèi)的所有版本的流量進(jìn)行精準(zhǔn)控制。默認(rèn)情況下請開啟,除非您明確知道關(guān)閉此選項(xiàng)的使用場景,否則請勿關(guān)閉此選項(xiàng)。
開啟標(biāo)簽染色 ?
推薦開啟,開啟后經(jīng)過此應(yīng)用的流量就只會(huì)在對應(yīng)的 Tag 環(huán)境中流轉(zhuǎn)。
開啟消息灰度 ?
請根據(jù)業(yè)務(wù)實(shí)際情況選擇是否開啟,目前僅支持 RocketMQ 4.2 及以上版本。
3 驗(yàn)證應(yīng)用是否接入成功
1.使用常見的 IDEA 啟動(dòng)應(yīng)用的方式進(jìn)行啟動(dòng)
2.登錄 MSE 控制臺(tái),選擇對應(yīng) Region ,找到剛才填寫的應(yīng)用名,點(diǎn)擊此應(yīng)用名,如果在應(yīng)用詳情中發(fā)現(xiàn)了本地對應(yīng)的 IP 和 Tag ,表明接入成功。.
注意,第一第二步只需要執(zhí)行一次,若 AppName 和 Tag 發(fā)生了變更,則根據(jù)實(shí)際情況進(jìn)行調(diào)整。
4 接入成功
現(xiàn)在,您可以在 IDEA 中盡情地享受本地開發(fā)部署和 debug 的快感。