工作中遇到一個項目需要在多個平臺編譯打包,每次都需要登錄到不同的服務器同步代碼,編譯,打包,上傳,非常麻煩,于是想為何不能一次操作,多臺服務器自動執行呢。
網上找了下,有很多解決方案,但是都比較麻煩,最后想到了用redis的消息訂閱實現該功能, 方法很簡單,只需要一個redis提供服務就可以,如果希望將功能web化,可以再加一個nginx服務,
實現方法如下:
1. 假設有三臺服務器A,B,C,需要執行相同的指令,可以在A機器上安裝一個redis-server, 一個nginx(帶redis2-nginx-module模塊), nginx訪問redis方法很簡單只需要參考官方教程就可以了。
2. 修改redis源碼文件redis-cli.c 在main函數任意位置添加該語句 `setvbuf(stdout, (char *)NULL, _IOLBF, 0);` 設置緩存區區為行緩存,這個很有必要,然后分別在A,B,C三臺服務器編譯一個redis-cli,用作redis客戶端.
3. 編寫腳本:
3.1 start.sh
#!/usr/bin/bash
while true;do
./redis-cli ?-h $A UBSCRIBE ?command_channel | xargs -i -exec sh command.sh {} ;
done
3.2 command.sh
#!/usr/bin/bash
input=($1)
case ${input[0]} in;
update)
update $@ | ./redis-cli -x ?set command_result_$IP
;;
*)
;;
esac
4. 運行腳本
在A,B,C三臺服務器建立一個目錄,將start.sh command.sh redis-cli放在同一個目錄下,
nohup sh start.sh &分別執行該命令啟動腳本
5. 發布命令
在任意服務器上執行 `./redis-cli -h $A publish?command_channel update` 發布一個任務,將分發到A,B,C三臺服務器上, 三臺服務器
6. 題外話
我在實際環境上是利用nginx 提供的http服務,發送命令給redis, 寫了個簡單的web頁面,實現任務分發, 并將處理結果保存到redis, ?前端通過nginx 從redis中獲取command_result_$IP中的值,作為處理結果,其中$IP為當前機器IP,或者其他唯一識別該機器的編號.
后面還實現升級功能,將command.sh 放在web服務器上供A,B,C下載,并在command.sh中實現update功能(1.重命名本地command.sh, 2.在nginx上下載新的command.sh, 下一次命令就會執行新的command.sh), 以這種方式,在不遠程連接服務器的情況下,實現對多臺服務器的同時操作的功能, 后面只需要修改command.sh 就可以添加各種命令,實現各種操作