以前的文章說過 由 PHP 轉到 Java 以後,很是不適應的一點就是代碼部署過程耗時長,調試不便,雖然可使用 debug,但有時候仍是須要修改代碼,從新部署測試機系統,整個流程須要:css
再加上須要兩臺機器切換操做,步驟之間不連貫,須要在邊上看着進度,以及時操做下一步。能夠說,等到想要的代碼上傳到測試機運行,花兒都謝了。html
做爲一個懶人,迫切地須要簡化一下流程,雖然可能達不到像 PHP 同樣秒傳文件當即生效,也要儘可能快且方便地部署測試包,別操這麼多心。本文就介紹我是怎麼一步步優化測試部署流程的。git
文章歡迎轉載,請尊重做者勞動成果,帶上原文連接:http://www.cnblogs.com/zhenbianshu/p/8733103.htmlgithub
剛入職時,對 Java 的部署相關一臉懵逼,有同事給了一個腳本和兩條命令,是爲最原始的「自動部署系統」:web
nc -4l xxPort > ROOT.war
;mvn clean package project
;nc testIp xxPort < test-1.0.0.war
;nc 是 NetCat 的簡稱,這個小工具用於同步兩臺服務器間的文件,使用時,先在接收端監聽一個端口並指定輸出文件,再在發送端鏈接 IP 和端口,並指定輸入流, nc 命令很簡單,網絡上資料也不少,這裏再也不多提了。算法
這個腳本雖然比所有手動好了一些,能幫我少輸兩個命令(nc 服務端、重啓命令),但是時間上並無縮短,但是烏龜似的上傳速度真的不能忍,這時我開始想着怎麼加速上傳。docker
其實一開始我是想從硬件方面解決這個問題的,即便用網線。爲此,買了一個網線轉接頭和一段網線,但是經過同事的設備測試發現轉接頭和網線都沒問題,但是接到一塊就不匹配(圍笑)。shell
窮則思變,接着我考慮從軟件方面解決這個問題。問了幾個同過後,發現有的同事在用 rsync 同步文件,但是 rsync 同步文件的單位不是文件
嗎?看了同事演示的上傳後,感受心態崩塌,很差好讀文檔的後果啊,走了好多彎路。apache
這裏簡要介紹一下 rsync 的使用:json
服務端須要啓動一個 rsync daemom 進程監聽某一端口,默認配置文件在 /etc/rsyncd.conf
,以 module
爲單位進行用戶認證、權限校驗、目標文件夾等配置,一個常見的 rsyncd 配置以下:
# general conf port=873 # 監聽端口 max connections=500 log file=/var/log/rsyncd.log pid file=/var/run/rsyncd.pid # pid 文件 # module 可多個 [zbs] path = /data1/zbs # zbs模塊的根目錄 read only=no use chroot=no uid=root gid=root auth users=zbs // 要進行用戶認證的用戶名 secrets file=/etc/rsyncd.scrt # 用戶名對應的密碼存放文件,每行一個,都是以 "zbs:password" 的形式 ignore errors exclude = .git/ # 排除掉 .git 文件夾
而在客戶端,咱們只須要使用 rsync [-option] fileOrDir rsync://{user}@{host}:{port}/{moduleName}/dir
就能夠將本地文件同步到服務端了。
至於密碼,可使用 --password-file=/path/to/pwdFile
的形式,也能夠在調用 rsync 命令以前設置環境變量:export RSYNC_PASSWORD=XXXX
;
至於 rsync 的同步算法, 推薦陳皓大神的文章:RSYNC 的核心算法
rsync 解決了上傳速度的問題,可是又引入了新的問題:我必須等着上傳結束,而且上傳結束後還要登錄測試機手動重啓 docker 服務,挺不方便的。
這時我開始打 rsync 源碼的主意了,rsync 是一個開源軟件,我考慮幫它加一個參數,讓它幫我在文件上傳結束後自動執行一些命令。
說作就作,從 rsync官網 下載到 rsync 的源碼開始查看並動手修改。rsync 的源碼代碼量仍是挺大的,不過修改它咱們不須要通讀,只修改讀取參數並使用就好了。我將這個問題分爲兩個步驟:
首先在 proto.h
文件裏添加函數聲明: char *lp_callback(int module_id);
讀取參數的相關代碼在 load_param.c
文件內,首先添加變量聲明、設置默認值,最後添加參數調用函數。
服務端文件同步的代碼在 clientserver.c
文件內,主體是 rsync_module
函數,前面的一系列操做如用戶認證、權限校驗等咱們能夠沒必要管,找到最後一步,在其調用下一次同步函數前 添加以下代碼(解釋在註釋中):
char * callback = lp_callback(i); // 讀取 callback 參數 if (callback != NULL && strlen(callback) != 0) { char cmd[strlen(callback) + 2]; strcpy(cmd, callback); strcat(cmd, " &"); // system 命令會阻塞,須要在命令上添加 & 讓它後臺執行 system(cmd); // 使用 stdlib 的 system 執行 callback 命令 }
修改後的源碼見:Github-zhenbianshu-rsyncCallback
這樣,我給本身上傳用的 module 添加一個腳本做爲 callback,在每次上傳完後,都會執行這個 callback 腳本,腳本里我能夠配置上服務的重啓,自動部署就實現了。
其實 tomcat 是能夠自動部署的,須要配置 server.xml
的 Host 元素,將 autoDeploy 屬性置爲 true,文檔:Tomcat Web Application Deployment。
但是咱們的服務是基於 docker-compose 進行部署的,若是修改 server.xml 還須要將文件映射到 docker image 裏。
其中 docker 能夠這麼配置:
FROM tomcat:7-jre8 COPY server.xml /usr/local/tomcat/conf/
docker-compose 能夠在 yml 配置文件裏添加以下配置:
image: tomcat-base volumes: - ./path/server.xml:/usr/local/tomcat/conf/server.xml - ./path/webapps:/data1/project/webapps
這樣,每當上傳了新的 war 包,tomcat 就會自動監測到並從新部署服務;
此時,還有一個需求, war 包同步完成,重啓完成後我不知道,得隨時關注 tomcat 的服務日誌,以儘快得知重啓結果,及時測試,若是服務重啓完就當即告訴我就最好了。
此時,我修改的 rsync 就有了做用了,使用 callback 參數在測試機啓動一個腳本以監測 tomcat 的服務日誌,服務重啓完成後會輸出 Server startup in xxx ms
,若是監測到有新的 log 輸出,則發送一個通知告訴我。
callback 參數配置的腳本相似於:
#!/bin/bash docker-compose stop -t 0 `rm /data1/project/webapps/ROOT -rf` sleep 1 docker-compose start sleep 5 # 這裏等待一會,使大量 tomcat 日誌覆蓋掉上一次重啓的結果日誌 date=`date "+%Y-%m-%d"` catalina_log="/data1/project/logs/catalina.$date.log" while : # 重複檢測日誌最後一行,直到輸出了重啓成功的標識 do finish=`tail -n 1 $catalina_log | grep 'Server startup'` if [ -n "$finish" ] then break fi sleep 0.1 done `curl -u "user:password" -d "uid=5715965217&text=succ" "messages/new.json"` # 調用接口發送通知
其實在測試機啓動一個守護進程用來實時監測日誌也是能夠的,可是須要處理日誌的新舊邏輯。
至於通知,有不少工具可使用,微博、QQ、微信、短信等通信工具都提供有對外的 http 接口,這個能夠依各人喜愛選擇使用。
最後把開發機上的 mvn 打包命令和 rsync 同步命令也包裝成腳本,以下所示:
#!/bin/bash mvn clean -DskipTests=true package -Pwar -am -pl project file=`find /path/to/project/target -name "*.war"` export RSYNC_PASSWORD=123456 rsync -avz $file rsync://zbs@IP:PORT/zbs/ROOT.war
再給腳本添加一個 alias 別名 alias test="myshell.sh"
,真正的一鍵部署就完成了,在部署測試環境時,只須要在項目目錄下輸入一條命令 test
就開始自動部署了,這時候能夠放手去喝杯水或作些其餘事,等收到消息通知後,回來繼續測試便可。
部門正在搭配 git 系統作自動部署測試系統,很是期待 push 過代碼後就能夠迅速測試的場景。果真,懶纔是第一輩子產力啊~
關於本文有什麼問題能夠在下面留言交流,若是您以爲本文對您有幫助,能夠點擊下面的 推薦
支持一下我,博客一直在更新,歡迎 關注
。