本文作者: CODING 使用者 - 何健
這次實戰篇,我們藉助「CODING 持續整合」,實現一個簡單的 Spring Boot 專案從編碼到最後部署的完整過程。本教程還有 B 站視訊版,幫助讀者更好地學習理解。
思路
線上上環境構建、測試、部署
這種情況,通常會將 jenkins 安裝在伺服器上,確保構建測試等操作環境和線上環境一致。
此時通常會在 jenkins 中配置好需要持續整合的倉庫,以及具體流程。
這種方式非常簡單粗暴,也非常有效,但是缺點也很明顯。可能 jenkins 會成為線上環境的旁站漏洞,這是非常不安全的。
那麼,我們就需要更高階的方式,可以線上環境之外的構建測試,最終部署到線上環境。「CODING 持續整合」正是提供這類持續整合模式的平臺。
不在實際部署伺服器上構建、測試
為了避免佔用線上伺服器的資源,也為了避免安全問題,我們可以使用單獨的 jenkins (或者其它此類軟體)完成構建、測試、分發,實際部署通過單獨的 webhook 實現。這樣就可以避免線上上環境安裝 Jenkins,還可以避免更復雜的系統安全維護。
這樣做的優點:不會影響線上服務; 缺點:部署地機器最好是可以公網訪問的,否則會無法完成後續分發步驟。
終極解決方案:使用 SaaS 化的 Jenkins
Software as a Service,軟體即服務。「CODING 持續整合」整合了 SaaS 化的 Jenkins 等主流企業開發流程工具,實現了 DevOps 流程全自動化。開箱即用,直接用它就好!
捋一下思路
我們這次實戰針對後一種思路
-
檢出程式碼
-
構建
-
測試
-
分發
-
觸發部署
實戰
實際體驗,還是很不錯的。
視訊地址:CODING 持續整合 - Spring Boot 專案
第一步:初始化一個持續整合
-
首先,我們需要進入準備持續整合的專案。
這裡我用 start.spring.io 初始化一個 demo 示例專案,並推送到倉庫。 為了方便大家,親自體驗,我準備了一個現成的倉庫,可以直接 git clone 下來再 git push 到自己賬戶下使用。倉庫地址:demoForCI
-
解壓 demo 專案,進入 demo 目錄,初始化倉庫。
cd g:\demo\
git init
git set remote giturl
git add ./
git commit -m 'init repo'
git push -u origin master
複製程式碼
別忘了 git config user.name yourname
和 git config user.email youremail
-
開始體驗 倉庫準備好後,就可以開始體驗「CODING 持續整合」。
第一次的使用,需要先建立一個 Jenkinsfile,很多小夥伴會說,第一次用,不知道是啥。
沒關係,「CODING 持續整合」已經給我們準備好了模板,非常容易理解,可以認為是特定格式語法寫一套 task 流程。
點選一下 “簡易模板”,更具實際情況修改一下就可以。
第二步:編寫 Jenkinsfile
為了方便理解,我們從簡易模板開始,分別修改對應階段的任務。
- 配置構建環境,「CODING 持續整合」目前支援 java-8、python-3.5、ruby-2.3、go-1.11 等等。 在 Jenkinsfile 的 pipeline 裡新增:
agent {
// 此處設定構建環境,目前可選有
// default, java-8, python-3.5, ruby-2.3, go-1.11 等
// 詳情請閱 https://dev.tencent.com/help/knowledge-base/how-to-use-ci#agents
label "java-8"
}
複製程式碼
-
檢出 這裡不得不說,「CODING 持續整合」這裡做的還是很方便的,提供了適用於好幾種不同場景的模板。預設簡易模板是帶有檢出部分的,我們可以根據實際情況進行修改。預設情況下,env.GIT_BUILD_REF 的值就是 master 主分支,實際上我們可以定製為其它專門用於構建發的分支。
這裡,大家可以自己修改具體要檢出的分支。
stage("檢出") {
steps {
sh 'ci-init'
checkout(
[$class: 'GitSCM', branches: [[name: env.GIT_BUILD_REF]],
userRemoteConfigs: [[url: env.GIT_REPO_URL]]]
)
}
}
複製程式碼
- 構建
stage("構建") {
steps {
echo "構建中..."
sh 'java -version'
sh 'mvn package'
echo "構建完成."
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true // 收集構建產物
}
}
複製程式碼
這裡需要注意,Spring Boot 的 pom 中需要新增一個外掛。 修改後:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 下面是新增的外掛 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
複製程式碼
- 測試 這裡我偷個懶,只做了單元測試, 沒有提取測試報告,大家可以根據實際專案定製這個流程。
stage("測試") {
steps {
echo "單元測試中..."
sh 'mvn test'
echo "單元測試完成."
//junit 'target/surefire-reports/*.xml' // 收集單元測試報告的呼叫過程
}
}
複製程式碼
-
分發 jar 包到目標伺服器 這裡比較無奈,我沒有單獨針對這次演示寫部署 jar 包和上傳 jar 包的 webhookApi,但是構建好的 jar 包需要要放置到待部署的伺服器。
於是有了這個過程,藉助 scp 和私鑰來上傳構建好的jar包。
這裡千萬記著提前部署好金鑰。並且將金鑰放到倉庫一份,用於分發jar包。
stage("分發jar包") {
steps {
echo "分發中..."
echo "chmod 600 pkey"
sh 'chmod 600 authorized_keys.pem'
echo "upload"
sh 'scp -i authorized_keys.pem ./target/*.jar root@yourip:/root/'
echo "準備部署"
}
}
複製程式碼
-
部署
前面有提到,這裡部署仍然需要觸發一個鉤子,否則只能手動部署了。 這裡我寫了一個最簡單的,實際上我們可以寫細緻一點,判斷一下介面返回的結果再根據結果輸出部署情況。
stage("部署") {
steps {
sh 'curl http://youapi'
echo "部署完畢"
}
}
複製程式碼
第三步:儲存 Jenkinsfile 並執行
修改好 Jenkinsfile 和 pom.xml。
我們要儲存 Jenkinsfile,編輯框可以直接編輯內容,編輯好可以直接提交到倉庫下的 ./Jenkinsfile
接下來, 平臺會自動讀取 Jenkinsfile 並開始走持續整合的流程:
持續整合的流程是可以看到的:
每個階段都對應 Jenkinsfile 一個 stage, 我們可以點選檢視對應階段的構建結果。
第四步:排查持續整合的報錯
如果某個過程出錯,「CODING 持續整合」的流程會停止,並提示失敗。此時我們可以進入具體節點檢視具體失敗原因。
比如現在是提示“分發 jar 包失敗”,那麼我們可以點選對應節點展開看看日誌,排查具體分發失敗的原因。
現在可以清晰地看到,報錯原因是我沒有填寫正確的主機 ip。
文中涉及的檔案及程式碼
Jenkinsfile
pipeline {
agent {
// 此處設定構建環境,目前可選有
// default, java-8, python-3.5, ruby-2.3, go-1.11 等
// 詳情請閱 https://dev.tencent.com/help/knowledge-base/how-to-use-ci#agents
label "java-8"
}
stages {
// 檢出倉庫
stage("檢出") {
steps {
// 這裡sh呼叫ci-init 初始化
sh 'ci-init'
// 這裡檢出倉庫,預設檢出分支為環境變數中的GIT_BUILD_REF
checkout(
[$class: 'GitSCM', branches: [[name: env.GIT_BUILD_REF]],
userRemoteConfigs: [[url: env.GIT_REPO_URL]]]
)
}
}
// 構建jar包
stage("構建") {
steps {
echo "構建中..."
// 輸出java版本
sh 'java -version'
// 呼叫maven 構建jar包
sh 'mvn package'
echo "構建完成."
//收集構建產物,這一步成功,我們就可以在平臺上看到構建產物
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true // 收集構建產物
}
}
// 測試
stage("測試") {
steps {
echo "單元測試中..."
// 做單元測試
sh 'mvn test'
echo "單元測試完成."
}
}
// 分發jar包,這裡只是簡單的通過scp分發jar包到目標機器指定目錄
stage("分發jar包") {
steps {
echo "分發中..."
echo "chmod 600 pkey"
sh 'chmod 600 authorized_keys.pem'
echo "upload"
sh 'scp -i authorized_keys.pem ./target/*.jar root@youip:/root/'
echo "準備部署"
}
}
// 部署jar包
stage("部署") {
// 這裡需要觸發一個部署的webhook,可以是一個很簡單的重啟java程式的操作
steps {
// 用curl 來觸發hook
sh 'curl http://baidu.com'
echo "請登入伺服器手動部署"
}
}
}
}
複製程式碼
pom.xml
文中所用 Spring Boot 示例專案的 pom.xml
實際上,大家可以直接去 start.spring.io 參考照這份 pom 來建立一個 demo。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>tech.hejian</groupId>
<artifactId>codingj8</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>codingj8</name>
<description>coding project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
複製程式碼
總結
CODING 是一個面向開發者的雲端開發平臺,提供 Git/SVN 程式碼託管、任務管理、線上 WebIDE、Cloud Studio、開發協作、檔案管理、Wiki 管理、提供個人服務及企業服務,其中「CODING 持續整合」整合了 SaaS 化的 Jenkins 等主流企業開發流程工具,實現了 DevOps 流程全自動化,為企業提供軟體研發全流程管理工具,打通了從團隊構建、產品策劃、開發測試到部署上線的全過程。