在傳統的單體軟體架構中,軟體開發、測試、運維都是以單個程式為單位。
當拆分成微服務之後,單個應用可以被拆分成多個微服務,比如使用者系統,可以拆分成基本資訊管理、積分管理、訂單管理、使用者資訊管理、合同管理等多個微服務模組。
這個時候對每個模組分別打包、釋出執行、開發、測試、運維的,對於測試、運維的工作量會極大增加。
在這個過程中,如果缺乏自動化測試、自動化整合/部署、自動運維等能力,帶來的影響是
- 軟體交付週期增加
- 多環境部署的情況下,各個環境差異帶來的問題。
- 人工運維容易給環境帶來一些不可重現的影響,而且一旦發生運維錯誤又比較難立刻恢復,造成故障處理時間較長。並且對於運維人員的能力要求較高
所有的這些問題,會導致軟體交付時間變長、風險增加、以及運維成本增加等問題。因此,我們需要一套自動化部署體系,來構建一個CICD的模型。
普通Jar包的執行方式
- 使用
maven package
nohup java -jar ${APP_NAME} > goods-service.log 2>&1 &
-
nohup用途:不結束通話地執行命令
-
&用途,在後臺執行
-
2>&1: 在bash中:
- 0 代表STDIN_FILENO 標準輸入(一般是鍵盤),
- 1 代表STDOUT_FILENO 標準輸出(一般是螢幕,準確的說是使用者終端控制檯),
- 2 三代表STDERR_FILENO (標準錯誤(出錯資訊輸出)。
2>&1就是用來將標準錯誤2重定向到標準輸出1中的。此處1前面的&就是為了讓bash將1解釋成標準輸出而不是檔案1。至於最後一個&,則是讓bash在後臺執行。
-
>
直接把內容生成到指定檔案
搭建Nexus私服環境
Nexus是一個強大的Maven倉庫管理器,它極大地簡化了本地內部倉庫的維護和外部倉庫的訪問。Nexus是一套“開箱即用”的系統不需要資料庫,它使用檔案系統加Lucene來組織資料。
Maven私服環境需要用sonatype nexus
,下面我們從安裝和配置進行詳細分析
部署伺服器: 192.168.8.138
下載和安裝
- 訪問:
https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.37.0-01-unix.tar.gz
地址,下載Sonatype Nexus。 - 解壓縮到
/data/program
目錄下
[root@localhost program]# tar -zxvf nexus-3.37.0-01-unix.tar.gz
- 進入到
${NEXUS_HOME}\bin
目錄,執行下面命令啟動Nexus
./nexus start
安裝Maven
- 下載Maven:
https://dlcdn.apache.org/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz
- 配置Maven 和JDK 環境變數。
export JAVA_HOME=/data/program/jdk1.8.0_241
export MAVEN_HOME=/data/program/apache-maven-3.8.4
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
-
進入到
${NEXUS_HOME}\bin
目錄,執行下面命令啟動Nexus用./nexus start啟動,後臺啟動,啟動成功後可以訪問
用./nexus run啟動,前臺啟動,顯示日誌,啟動後可以訪問
./nexus start
啟動時,會有如下提示,這個是建議我們使用非
root
賬戶來訪問。
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
- 訪問:
http://localhost:8081
訪問Nexus倉庫
如果想配置 nexus 的應用在本地啟動的 JVM引數,可以在 nexus.vmoptions
如果想改變 nexus 的 埠號,可以在 nexus-default.properties
登入控制檯
- 預設登入的帳號是
admin
,密碼在會提示你在:/data/program/sonatype-work/nexus3/admin.password
檔案中。
- 內容如下,直接複製該內容登入即可。
090849ac-cea7-4353-b2c8-59b2bceadb50
Nexus控制檯說明
進入Nexus控制檯的Browse
選單,可以看到四種倉庫型別:
1)maven-central: maven中央庫,預設從https://repo1.maven.org/maven2/拉取jar
2)maven-releases: 私庫發行版jar
3)maven-snapshots:私庫快照(除錯版本)jar
4)maven-public: 倉庫分組,把上面三個倉庫組合在一起對外提供服務,在本地maven基礎配置settings.xml中使用。
Nexus預設的倉庫型別有以下四種:(上面的名字可以隨便取,關鍵是它對應的是什麼倉庫型別)
1)group(倉庫組型別):又叫組倉庫,用於方便開發人員自己設定的倉庫;
2)hosted(宿主型別):內部專案的釋出倉庫(內部開發人員,釋出上去存放的倉庫);
3)proxy(代理型別): 從遠端中央倉庫中尋找資料的倉庫(可以點選對應的倉庫的Configuration頁簽下Remote Storage Location屬性的值即被代理的遠端倉庫的路徑);
4)virtual(虛擬型別): 虛擬倉庫(這個基本用不到,重點關注上面三個倉庫的使用);
Nuget是用於微軟.NET開發平臺的軟體包管理器,和Maven類似。
目錄說明
nexus-3.34.0-01 目錄
- bin 包含nexus的啟動指令碼和相關配置
- etc jetty、karaf等配置檔案
- jre jre環境
- lib java架包庫
- public 關於nexus應用在本地跑起來所需要的資源
- system 應用所有的外掛和元件
- LICENSE.txt 和 NOTICE.txt 版權宣告和法律細則
sonatype-work\nexus3 目錄
- blobs/ 建立blob的預設路徑,當然也可以重新指定
- cache/ 當前快取的karaf包的資訊
- db/ OrientDB資料庫的資料,用於儲存nexus的後設資料的資料庫
- elasticsearch/ 當前配置的Elasticsearch狀態
- etc/ 大概是執行時配置狀態和關於資源庫的自定義的相關的東西
- health-check/ 看目錄,健康檢查的相關報告的儲存目錄吧
- keystores/ 自動生成的關於資源庫的ID主鍵
- log/ 執行例項生成的日誌檔案,也有日誌檔案的壓縮包,貌似是每天都會生成日誌檔案,你可以定期刪除老的日誌檔案
- tmp/ 用於儲存臨時檔案的目錄
Nexus設定成系統服務
按照以下步驟執行
- 修改
${NEXUS_HOME}\bin\nexus
這個指令碼,增加下面的配置
INSTALL4J_JAVA_HOME_OVERRIDE=/data/program/jdk1.8.0_241
- 設定軟連結
[root@localhost bin]# ln -s /data/program/nexus-3.37.0-01/bin/nexus /etc/init.d/nexus
- 通過chkconfig方式配置系統服務
cd /etc/init.d
sudo chkconfig --add nexus #新增nexus服務
sudo chkconfig --levels 345 nexus on #設定開啟自啟動
-
啟動和停止服務
sudo service nexus start #開啟服務
service nexus status #檢視服務狀態
搭建Gitea環境
- 安裝git環境:
yum -y install git
。 - 通過下面的命令下載linux中的安裝包到
/data/program/gitea
目錄下。
wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64
- 執行
chmod +x gitea
命令,授予執行許可權 - 執行下面這個命令執行gitea
./gitea web
安裝成系統服務(重要)
- 建立Git使用者
sudo useradd \
--system \
--shell /bin/bash \
--comment 'Git Version Control' \
--create-home \
--home /home/git \
git
- 下載二進位制檔案
wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64
-
根據gitea官方推薦,按照以下方式配置gitea的安裝目錄
-
把下載的檔案移動到
/usr/local/bin
目錄sudo mv /data/program/gitea /usr/local/bin
-
使二進位制檔案可執行:
chmod +x /usr/local/bin/gitea
-
按照一下命令建立必要目錄並設定許可權
sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log} sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log} sudo chown git: /var/lib/gitea/{data,indexers,custom,public,log} sudo chmod 750 /var/lib/gitea/{data,indexers,log} sudo mkdir /etc/gitea sudo chown root:git /etc/gitea sudo chmod 770 /etc/gitea
-
根據Gitea官方提供的Systemd Unit檔案,配置系統服務。
sudo wget https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/systemd/gitea.service -P /etc/systemd/system/
注意,gitea.service, 不能通過wget下載,需要去github上覆制
-
完成上述過程後,通過下面命令開啟自動啟動
systemctl enable gitea systemctl start gitea
-
-
安裝啟動完成後,訪問:
http://192.168.8.136:3000
,配置資料庫相關屬性即可。
搭建Jenkins環境
Jenkins是一個用JAVA編寫的開源的持續整合工具,執行在servlet容器中,支援軟體配置管理(SCM)工具,可以執行基於APACHE ANT和APACHE MAVEN的專案,以及任意Shell指令碼和Windows批處理命令
Jenkins提供了自動構建和部署的功能,具體安裝方式如下:
wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum upgrade
yum install epel-release java-11-openjdk-devel
yum install jenkins
systemctl daemon-reload
通過下面的命令啟動或停止jenkins
systemctl start jenkins
systemctl stop jenkins
訪問: http://192.168.8.136:8080 訪問jenkins
按照控制檯提示的步驟一步步執行即可。
注意: Jenkins安裝預設採用JENKINS使用者,所以如果是使用root許可權,則需要修改帳號
[root@localhost bin]# vim /etc/sysconfig/jenkins
JENKINS_USER="root"
專案改造
專案配置本地的私服
-
修改
setting.xml
檔案,增加mirror
配置<mirrors> <mirror> <id>nexus</id> <mirrorOf>maven-public</mirrorOf> <url>http://192.168.8.136:8081/repository/maven-public/</url> </mirror> </mirrors>
mirror相當於一個攔截器,它會攔截maven對remote repository的相關請求,走該映象進行jar包的獲取。
-
在專案中增加如下配置,也就是指定snapshots和releases 不同發行版本jar包的釋出倉庫
<distributionManagement> <snapshotRepository> <id>snapshots</id> <name>Nexus Snapshot Repository</name> <url>http://192.168.8.136:8081/repository/maven-snapshots/</url> </snapshotRepository> <repository> <id>releases</id> <name>Nexus Release Repository</name> <url>http://192.168.8.136:8081/repository/huhy-nexus/</url> </repository> </distributionManagement>
修改釋出伺服器的settings.xml檔案
修改釋出伺服器的settings.xml檔案的目的,是因為Jenkins伺服器在進行持續整合時,需要通過maven實現依賴jar包的下載,而這個下載需要從我們本地的私服中獲取。
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>maven-public</mirrorOf>
<url>http://192.168.8.136:8081/repository/maven-public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexusRep</id>
<repositories>
<repository>
<id>nexus</id>
<url>http://192.168.8.136:8181/repository/maven-public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<!--外掛地址-->
<id>nexus</id>
<url>http://192.168.8.136:8181/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexusRep</activeProfile>
</activeProfiles>
配置自動整合與釋出
配置Jenkins的環境變數
進入到如下頁面,紅色標註的配置。
配置Maven的環境,指定釋出伺服器上安裝的Maven目錄。
安裝Jenkins外掛
-
Gitea , 整合Gitea,安裝好之後,在Jenkins全域性配置中,新增Gitea Server資訊。
-
Git Parameter , 配置Git釋出屬性
-
Publish Over SSH ,在遠端機器上執行指令碼,這一步需要先配置能ssh遠端機器
-
Maven Integration, 支援Maven專案的整合
配置釋出目標伺服器資訊
我們把下面兩臺伺服器當成是web節點
- 192.168.8.134
- 192.168.8.135
在Jenkins 全域性配置中,配置這兩臺伺服器的資訊,用來後續實現jar包遠端傳輸。其中Remote Directory
目標伺服器的工作目錄,jar包會被遠端傳輸到該目錄下
新增專案釋出機制
建立一個Maven專案的任務。
配置原始碼來源,這裡使用Gitea中專案的原始碼地址,並配置登入帳號密碼資訊。
配置Maven的執行命令,其中
root POM
,如果是在多模組專案中,需要指定當前要構建的模組的pom.xml。
增加構建成功之後的執行邏輯,就是把jar包釋出到遠端目標伺服器,然後執行相關shell指令碼啟動服務
編寫釋出指令碼
編寫shell指令碼,當jar包傳送到目標伺服器之後,執行下面指令碼。
- 做歷史jar備份和清理
- 執行shell指令碼啟動服務
#! bin/sh -e
export JAVA_HOME=/data/program/jdk1.8.0_241
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=${PATH}:$JAVA_HOME/bin
source /etc/profile
# define property
JAR_PATH='/app/service/goods-service'
TEMP_PATH='/app/service/temp'
BACKUP_PATH='/app/service/backup'
JAR_NAME=goods-service.jar
FILE_NAME=goods-service
# stop target service
cd ${JAR_PATH}
sh run-goods-service.sh stop
sleep 2
rm -rf $FILE_NAME.log
# backup old jar
BACKUP_DATE=$(date +%Y%m%d_%H%M)
if [ ! -d $JAR_PATH/backup/$FILE_NAME ];then
mkdir -p $JAR_PATH/backup/$FILE_NAME
fi
cd ${JAR_PATH}
pwd
if [ -f $JAR_NAME ];then
mv -f ./$JAR_NAME ./backup/$FILE_NAME/$JAR_NAME$BACKUP_DATE
sleep 1
fi
# start jar
BUILD_ID=dontKillMe
cd ${TEMP_PATH}
mv -f $JAR_NAME $JAR_PATH
cd ${JAR_PATH}
sh run-goods-service.sh restart
# clear old backup
cd ${JAR_PATH}/backup/$FILE_NAME
ls -lt|awk 'NR>5{print $NF}' |xargs rm -rf
ps -ef|grep java
echo "=============deploy success========"
編寫執行指令碼run-goods-service.sh
# 表示當前指令碼採用/bin路徑的bash程式來解釋執行
#!/bin/bash
# 執行的jar包
APP_NAME=goods-service.jar
usage() {
echo "執行操作命令 [start|stop|restart|status]"
exit 1
}
if_exist() {
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
start() {
if_exist
if [ $? -eq 0 ]; then
echo "${APP_NAME} already running . pid=${pid}"
else
nohup java -jar ${APP_NAME} > goods-service.log 2>&1 &
npid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
echo "start ${APP_NAME} success, pid=${npid}"
fi
}
stop() {
if_exist
if [ $? -eq 0 ]; then
kill -9 $pid
echo "stop $pid success".
else
echo "${APP_NAME} is not running"
fi
}
status() {
if_exist
if [ $? -eq 0 ]; then
echo "${APP_NAME} is running. pid is ${pid}"
else
echo "${APP_NAME} is not running "
fi
}
restart() {
stop
sleep 5
start
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac
配置程式碼提交後動態構建
如果我們希望程式碼提交合併到某個分支後,自動構建進行釋出,怎麼實現呢?
安裝Webhook外掛
-
在Jenkins中安裝
Generic Webhook Trigger
外掛,安裝成功後,會在構建的配置頁面多了下面所示的一個選項。 -
配置
Generiac Webhook Trigger
,增加一個token作為驗證。注意這個地址: http://JENKINS_URL/generic-webhook-trigger/invoke , 在webhook中需要配置這個作為觸發呼叫。
gitea新增webhook鉤子
-
在gitea的專案中,找到
Web鉤子
,新增Web鉤子
. 選擇gitea
。 -
新增webhook
驗證自動觸發的行為
-
修改gpmall-pc這個專案的任何一個程式碼,然後提交到gitea上。
-
觀察Jenkin的專案構建目錄,會增加一個自動構建的任務,如下圖所示。
-
並且在gitea的webhook中,可以看到最近的推送記錄
原始碼地址
文章演示使用的原始碼: https://github.com/2227324689/spring-cloud-netflix-example.git
版權宣告:本部落格所有文章除特別宣告外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自
Mic帶你學架構
!
如果本篇文章對您有幫助,還請幫忙點個關注和贊,您的堅持是我不斷創作的動力。歡迎關注「跟著Mic學架構」公眾號公眾號獲取更多技術乾貨!