選單

本地同時啟停多箇中間件的優雅方案

“I don’t care if it works on your machine! We are not shipping your machine!” - Vidiu Platon

“我才不管它能不能在你的機器上執行捏!我們又不會給你提供機器!” —— 韋都·柏拉圖

0x00 大綱#

目錄

0x00 大綱

0x01 前言

0x02 大公司的解決方案

0x03 小作坊的解決方案試作一號啟動指令碼停止指令碼最終版本

0x04 小結應用啟停困難外部系統不穩定

0x01 前言#

隨著微服務架構風格的推廣應用,開發人員的本地開發和除錯成本大大提高,甚至不堪重負。動不動就要依賴一攬子東西,註冊中心、Redis、MQ、基礎服務ABC……等等。

開發人員如果手工在本地啟停多個基礎服務和中介軟體,將會浪費大量時間,降低開發效率。

0x02 大公司的解決方案#

Docker和Kubernetes,不缺錢也不缺人的首選。什麼雙活、負載均衡統統來個四五套,把寒氣也傳給運維人員。

0x03 小作坊的解決方案#

為了節約成本,當然是要在本地啟動一整套系統節點啦,畢竟記憶體成本比人力成本低得多。但是手工啟停太浪費時間了,這樣會導致本來就不多的摸魚時間所剩無幾。人生苦短,我用指令碼。

確定了方案,我就開始著手編排了,以一個Zookeeper + Redis(一主二從三哨兵)的啟停指令碼為目標,配置過程就略過了,著重解決啟停的問題。

試作一號#

啟動指令碼#

@echo offcolor 5ftitle fake-dockerecho ^>^>^>^>^>^>^>^>bootstrapping redis。。。start “redis-master” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。master-1。conf”start “redis-slaver-1” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。slaver-1。conf”start “redis-slaver-2” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。slaver-2。conf”start “redis-sentinel-1” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。sentinel-1。conf” ——sentinelstart “redis-sentinel-2” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。sentinel-2。conf” ——sentinelstart “redis-sentinel-3” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。sentinel-3。conf” ——sentinelecho ^>^>^>^>^>^>^>^>done!echo ^>^>^>^>^>^>^>^>bootstrapping zookeeper。。。start “zookeeper-dev” “c:\dev\apache-zookeeper-3。6。3-bin\bin\zkServer。cmd”echo ^>^>^>^>^>^>^>^>system is hot!

停止指令碼#

@echo offcolor 5fecho ^>^>^>^>^>^>^>^>shutdowning。。。taskkill /t /f /fi “imagename eq redis-server。exe” >nultaskkill /t /f /fi “windowtitle eq zookeeper-dev” >nulecho ^>^>^>^>^>^>^>^>system is down!pause>nul

第一個版本,解決了啟動和停止的問題,但是是手動檔的,重啟中介軟體的話要執行兩個指令碼。待改進的問題有兩個:

重啟不方便,儘量做到一鍵啟停

彈出視窗太多,體驗不佳

第一個問題容易解決,先停後起,先執行停止指令,再把應用拉起來。

第二個問題有點麻煩,一開始想嘗試無視窗啟動,反覆嘗試未果,後來採用了折中方案,在CMD的start命令幫助中有如下描述:

C:\Users\Master>help start

啟動一個單獨的視窗以執行指定的程式或命令。

START [“title”] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]

[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]

[/NODE ] [/AFFINITY ] [/WAIT] [/B]

[command/program] [parameters]

“title” 在視窗標題欄中顯示的標題。 path 啟動目錄。 B 啟動應用程式,但不建立新視窗。 應用程式已忽略 ^C 處理。除非應用程式 啟用 ^C 處理,否則 ^Break 是唯一可以中斷 該應用程式的方式。 I 新的環境將是傳遞 給 cmd。exe 的原始環境,而不是當前環境。 MIN 以最小化方式啟動視窗。 MAX 以最大化方式啟動視窗。 SEPARATE 在單獨的記憶體空間中啟動 16 位 Windows 程式。 SHARED 在共享記憶體空間中啟動 16 位 Windows 程式。 LOW 在 IDLE 優先順序類中啟動應用程式。 NORMAL 在 NORMAL 優先順序類中啟動應用程式。 HIGH 在 HIGH 優先順序類中啟動應用程式。 REALTIME 在 REALTIME 優先順序類中啟動應用程式。 ABOVENORMAL 在 ABOVENORMAL 優先順序類中啟動應用程式。 BELOWNORMAL 在 BELOWNORMAL 優先順序類中啟動應用程式。 NODE 將首選非一致性記憶體結構(NUMA)節點指定為 十進位制整數。 AFFINITY 將處理器關聯掩碼指定為十六進位制數字。

根據描述,如果start時帶上/b引數,就能讓多個程式在一個視窗中寄宿。修改後得到最終版本:

最終版本#

@echo offcolor 5ftitle %date%echo ^>^>^>^>^>^>^>^>cleaning up context。。。echo ^>^>^>^>^>^>^>^>killing previous runner。。。taskkill /t /f /fi “imagename eq redis-server。exe” >nultaskkill /t /f /fi “windowtitle eq fake-docker*” >nultimeout /t 3 /nobreak >nulrd /s /q “c:\tmp\zookeeper”>nulecho ^>^>^>^>^>^>^>^>clean up context done!title fake-dockerecho ^>^>^>^>^>^>^>^>bootstrapping redis。。。start /b “redis-master” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。master-1。conf”start /b “redis-slaver-1” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。slaver-1。conf”start /b “redis-slaver-2” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。slaver-2。conf”start /b “redis-sentinel-1” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。sentinel-1。conf” ——sentinelstart /b “redis-sentinel-2” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。sentinel-2。conf” ——sentinelstart /b “redis-sentinel-3” “c:\dev\redis-x64-3。2。100\redis-server。exe” “c:/dev/redis-x64-3。2。100/redis。sentinel-3。conf” ——sentinelecho ^>^>^>^>^>^>^>^>done!echo ^>^>^>^>^>^>^>^>bootstrapping zookeeper。。。start /b “zookeeper-dev” “c:\dev\apache-zookeeper-3。6。3-bin\bin\zkServer。cmd”echo ^>^>^>^>^>^>^>^>system is hot!

最終版本,實現了一鍵啟停,只會產生一個命令列視窗,屬於能用的範疇了。在此基礎上,可以根據專案情況,自行新增其他中介軟體或基礎服務的啟停命令。

0x04 小結#

分散式應用除錯和部署不可避免會面臨幾個問題:

應用啟停困難#

通常由於架構的原因,為了除錯某個中間節點或上游應用的功能,需要把相關的應用都啟動起來,如果手工啟停,無疑是痛苦的。

外部系統不穩定#

如果不能把整個系統都在本地啟動起來,那麼本地就會有一部分服務依賴於外部公共環境,它們通常不止一個人甚至不止一個團隊在用。 一旦外部服務不可用,就會影響到本地的開發和測試。

因此準備一個微型本地開發環境是有必要的,至少在開發和除錯階段。況且如果最困難的啟停問題被解決了,何樂不為呢?