CI/CD入門
CI/CD入門
一、程式碼上線方案
1、早期手動部署程式碼
-
純手動Scp、Rsync上傳程式碼。
-
純手動登陸,Git pull 或者 Svn update。
-
純手動xftp、ftp、filezilla上傳程式碼。
-
開發傳送壓縮包,rz上傳,解壓部署程式碼。
缺點:
-
全程運維參與,佔用大量時間。
-
如果節點多,上線速度慢。
-
人為失誤多,目錄管理混亂。
-
回滾不及時,或者難以回退。
上線方案示意圖:
2、合理化上線方案
-
開發人員(rd)需在個人電腦搭建LAMP環境測試開發好的網站程式碼,並且在辦公室或 IDC機房的測試環境測試通過,最好有專職測試人員(ts)。
-
程式程式碼上線要規定時間,例如:三天上線一次,如網站需經常更新可每天下午 20 點上線,這個看網站業務性質而定,原則就是影響使用者體驗最小。
-
程式碼上線之前需備份,網站程式出了問題方便回退,另外,從上線技巧上講,上傳程式碼時儘可能先傳到伺服器網站臨時目錄,傳完整後一步mv過去,或者通過In做軟連結— 線上更新程式碼的思路。如果嚴格更新,把應用伺服器從叢集節點平滑下線,然後更新。
-
儘量由運維人員管理上線,對於程式碼的功能性,開發人員更在意,而對於程式碼的效能優化和上線後伺服器的穩定,運維更在意伺服器的穩定,因此,如果網站宕機問題歸運維管,就要讓運維上線,這樣更規範科學。否則,開發隨意更新,出了問題運維負責,這樣就錯了,運維永遠無法抬頭。
web程式碼規範化上線流程圖
3、大型企業上線制度和流程
JAVA程式碼環境上線時,有數臺機器同時需要更新或者分批更新
-
本地開發人員取svn程式碼。當天上線提交到trunk,否則,長期專案單開分支開發,然後在合併主線(trunk)
-
辦公內網開發測試時,由開發人員或配置管理員通過部署平臺jenkins實現統一部署,(即在部署平臺上控制開發機器從svn取程式碼,編譯,打包,釋出到開發機,包名如idc_dep.war).
-
開發人員通知或和測試人員一起測試程式,沒有問題後,由配置管理員打上新的tag標記。這裡要注意,不同環境的配置檔案是隨程式碼同時釋出的。
-
配置管理員,根據上一步的tag標記,checkout出上線程式碼,並配置好IDC測試環境的所有配置,執行編譯,打包(mvn,ant)(php不需要打包),然後釋出到IDC內的統一分發伺服器。
-
配置管理員或SA上線人員,把分發的程式程式碼內容推送到相關測試伺服器(包名如idc_test.war),然後通知開發及測試人員進行測試。如果有問題向上回退,繼續修改。
-
如果IDC測試沒有問題,繼續打好tag標記,此時,配置管理員,根據上步的tag標記,checkout出測試好的程式碼,並配置好IDC正式環境的所有配置,執行編譯,打包(mvn,ant)(php不需要打包),然後釋出到IDC內的統一分發伺服器主機,準備批量釋出。
-
配置管理員或SA上線人員,把分發的內容推送到相關正式伺服器(包名如idc_product.war),然後通知開發及測試人員進行測試。如果有問題直接釋出回滾指令。
IDC正式上線的過程對於JAVA程式,可以是AB組分組上線的思路,即平滑下線一半的伺服器,然後釋出更新程式碼,重啟測試,無問題後,掛上更新後的伺服器,同時再平滑下線另一半的伺服器,然後釋出更新程式碼測試(或者直接釋出後,重啟,掛上線)
4 、php程式程式碼上線的具體方案
對於PHP上線方法:釋出程式碼時(也需要測試流程)可以直接釋出到正式線臨時目錄 ,然後mv或更改link的方式釋出到正式上線目錄 ,不需要重啟http服務。這是新朗,趕集的上線方案。
5 、Java程式程式碼上線的具體方案
對於java上線方法:較大公司需要分組平滑上線(如從負載均衡器上摘掉一半的伺服器),釋出程式碼後,重啟伺服器測試,沒問題後,掛上上好線的一半,再下另外一半。如果前端有DNS智慧解析,上線還可以分地區上線若干伺服器,逐漸普及到全國的伺服器,這個被稱為“灰度釋出”,在後面門戶網站上線的知識裡我們在講解。
6 、程式碼上線解決方案注意事項
上線的流程裡,辦公室測試環境-->IDC測試環境-->正式生產環境,所有環境中的所有軟體均應版本統一,其次儘量單一,否則將後患無窮,開發測試成功,IDC測試就可能有問題(如:作業系統,web伺服器,jdk,php,tomcat,resin等版本)
-
開發團隊小組辦公內部測試環境測試(該測試環境屬於開發小組維護,或定時自動更新程式碼),程式碼有問題返回給某開發人員重新開發。
-
有專門的測試工程師,程式有問題直接返回給開發人員(此時返回的一般為程式的BUG,稱為BUG庫),無問題進行IDC測試
-
IDC測試由測試人員和運維人員參與,叫IDCtest,進行程式的壓力測試,有問題直接返回給開發人員,無問題進行線上環境上線。
-
數臺伺服器程式碼分發上線方案舉例(JAVA程式)
A:假設同業務伺服器有6臺,將伺服器分為A,B兩組,A組三臺,B組三臺,先對A組進行從負載均衡器上平滑下線,B組正常提供服務,避免伺服器因上線影響業務。
B:下線過程是通過指令碼將A組伺服器從RS池(LVS,NGINX,HAPROXY,F5等均有平滑方案)中踢出,避免負裁均衡器將請求傳送給A組伺服器(此時的時間應該為網站流量少時,一般為晚上)
C:將程式碼分發到A組伺服器的站點目錄下,對A組伺服器上線並重啟服務,並由專業的測試人員進行訪問測試,測試成功後,掛上A組的伺服器,同時下線B組伺服器,B組程式碼上線操作測試等和A組相同,期間也要觀察上線提供服務的伺服器狀況,有問題及時回滾。
-
如果是PHP程式,則上線可以簡單化,直接將上線程式碼(最好全量)釋出到所有上線伺服器的特定目錄後,分發完成後,一次性mv或ln到站點目錄,當然測試也是少不了的。測試除了人員測試外,還有各種測試指令碼測試各個相關業務介面。
二、理解持續整合、持續交付、持續部署
軟體開發的連續方法基於自動執行指令碼,以最大限度地減少在開發應用程式時引入錯誤的可能性。從新程式碼的開發到部署,它們需要較少的人為干預甚至根本不需要干預。它涉及在每次小迭代中不斷構建,測試和部署程式碼更改,從而減少基於有缺陷或失敗的先前版本開發新程式碼的機會。有三種主要方法,分別為持續整合、持續交付、持續部署,每種方法都根據最適合您的策略進行應用。
1、持續整合
程式碼合併,構建,部署,測試都在一起,不斷地執行這個過程,並對結果反饋。
持續整合(英語:Continuous integration,縮寫為 CI),一種軟體工程流程,將所有工程師對於軟體的工作複本,每天整合數次到共用主線(mainline)上。
這個名稱最早由葛來迪·布區(Grady Booch)在他的布區方法中提出,但是他並沒有提到要每天整合數次。之後成為極限程式設計(extreme programming,縮寫為XP)的一部分。在測試驅動開發(TDD)的作法中,通常還會搭配自動單元測試。
持續整合的提出,主要是為了解決軟體進行系統整合時面臨的各項問題,極限程式設計稱這些問題為整合地獄(integration hell)。
持續整合主要是強調開發人員提交了新程式碼之後,立刻進行構建、(單元)測試。根據測試結果,我們可以確定新程式碼和原有程式碼能否正確地整合在一起。簡單來講就是:頻繁地(一天多次)將程式碼整合到主幹。
持續整合的目的
-
及早發現整合錯誤且由於修訂的內容較小所以易於追蹤,這可以節省專案的時間與成本。
-
避免釋出日期的前一分鐘發生混亂,當每個人都會嘗試為他們所造成的那一點點不相容的版本做檢查。
-
當單元測試失或發生錯誤,若開發人員需要在不除錯的情況下還原始碼庫到一個沒有問題的狀態,只需要放棄一小部分的更改 (因為整合的次數頻繁)。
-
讓 "最新" 的程式可保持可用的狀態供測試、展示或釋出用。
-
頻繁的提交程式碼會促使開發人員建立模組化,低複雜性的程式碼。
-
防止分支大幅偏離主幹。如果不是經常整合,主幹又在不斷更新,會導致以後整合的難度變大,甚至難以整合。
2、持續交付
部署到測試環境、預生產環境
持續交付(英語:Continuous delivery,縮寫為 CD),是一種軟體工程手法,讓軟體產品的產出過程在一個短週期內完成,以保證軟體可以穩定、持續的保持在隨時可以釋出的狀況。
它的目標在於讓軟體的建置、測試與釋出變得更快以及更頻繁。這種方式可以減少軟體開發的成本與時間,減少風險。
持續交付在持續整合的基礎上,將整合後的程式碼部署到更貼近真實執行環境的「類生產環境」(production-like environments)中。比如,我們完成單元測試後,可以把程式碼部署到連線資料庫的Staging 環境中更多的測試。如果程式碼沒有問題,可以繼續手動部署到生產環境中。
3、持續部署
將最終產品釋出到生成環境,給使用者使用
持續部署(英語:Continuous Deployment,縮寫為 CD),是持續交付的下一步,指的是程式碼通過評審以後,自動部署到生產環境。
有時候,持續部署也與持續交付混淆。持續部署意味著所有的變更都會被自動部署到生產環境中。持續交付意味著所有的變更都可以被部署到生產環境中,但是出於業務考慮,可以選擇不部署。如果要實施持續部署,必須先實施持續交付。
持續部署即在持續交付的基礎上,把部署到生產環境的過程自動化。
三、Maven 私服 Nexus3
1、Maven和Nexus3 簡介
Maven是一個採用純Java編寫的開源專案管理工具
採用一種被稱之為Project Object Model(POM)概念來管理專案,所有的專案配置資訊都被定義在一個叫做POM.xml的檔案中, 通過該檔案Maven可以管理專案的整個生命週期,包括清除、編譯,測試,報告、打包、部署等等。
目前Apache下絕大多數專案都已經採用Maven進行管理. 而Maven本身還支援多種外掛, 可以方便更靈活的控制專案, 開發人員的主要任務應該是關注商業邏輯並去實現它, 而不是把時間浪費在學習如何在不同的環境中去依賴jar包,專案部署等。
Maven和ant都是軟體構建工具(軟體管理工具),Maven比Ant更加強大,已經取代了ant,jar包的宣告式依賴描述。Maven有jar包的倉庫。
私服是架設在區域網的一種特殊的遠端倉庫,目的是代理遠端倉庫及部署第三方構件。有了私服之後,當 Maven 需要下載構件時,直接請求私服,私服上存在則下載到本地倉庫;否則,私服請求外部的遠端倉庫,將構件下載到私服,再提供給本地倉庫下載。
公司如果沒有maven私服,則需要用手動打jar包的方式新增依賴
2、安裝 Maven
1、下載 maven
[[email protected] ~]# wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
2、解壓安裝
[[email protected] ~]# tar xf apache-maven-3.5.4-bin.tar.gz -C /usr/local/
[[email protected] ~]# cd /usr/local/
[[email protected] ~]# ln -s apache-maven-3.5.4/ maven
3、安裝 java 環境
[[email protected] ~]# tar xf jdk-8u201-linux-x64.tar.gz -C /usr/local/
[[email protected] ~]# cd /usr/local/
[[email protected] ~]# ln -s jdk1.8.0_201/ java
4、新增環境變數
[[email protected] ~]# vim /etc/profile
新增如下內容(這裡的MAVEN_HOME需要改為你自己的maven解壓目錄):
JAVA_HOME=/usr/local/java
export MAVEN_HOME=/usr/local/maven
export JRE_HOME=/usr/local/java/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$MAVEN_HOME/bin:$PATH
- 過載環境變數
[[email protected] ~]# source /etc/profile
5、驗證 maven 安裝
輸入命令 mvn -version 看到如下內容說明安裝成功了。
3、安裝 nexus3
1、下載
專業版的nexus收費,下載開源版 Nexus OSS,下載地址為 https://www.sonatype.com/download-oss-sonatype
Wing下載的時候可以獲取連結用迅雷下載,我是直接把https改成了http下載,下載下來的包大小不一樣,我暫時使用的是小一點的120多M的安裝包
2、解壓
[[email protected] ~]# cd /usr/local
[[email protected] ~]# tar -zxf nexus-3.13.0-01-unix.tar.gz
解壓後會多出兩個目錄,nexus-3.13.0-01和sonatype-work。
3、啟動
[[email protected] ~]# cd nexus-3.13.0-01/bin/
[[email protected] ~]# ./nexus start
看到如圖所示內容表明我們已經啟動成功了,遊覽器輸入http://localhost:8081即可訪問。
注意:
啟動後如果你立即訪問可能發現什麼都沒有,不要急這個啟動需要一定時間,1分鐘後再嘗試訪問
登入 :
點選右上角的sign in登入,輸入賬戶admin
密碼:
# cat /root/sonatype-work/nexus3/admin.password
91c37108-809a-495b-942d-3932b9b33e04
4、倉庫介紹
點選“設定-Repositories”,就可以看到倉庫,分三種類型:
-
proxy:是遠端倉庫的代理。比如說在nexus中配置了一個central repository的proxy,當用戶向這個proxy請求一個artifact,這個proxy就會先在本地查詢,如果找不到的話,就會從遠端倉庫下載,然後返回給使用者,相當於起到一箇中轉的作用。
-
Hosted:是宿主倉庫,使用者可以把自己的一些構件,deploy到hosted中,也可以手工上傳構件到hosted裡。比如說oracle的驅動程式,ojdbc6.jar,在central repository是獲取不到的,就需要手工上傳到hosted裡,一般用來存放公司自己的jar包;
-
Group:是倉庫組,在maven裡沒有這個概念,是nexus特有的。目的是將上述多個倉庫聚合,對使用者暴露統一的地址,這樣使用者就不需要在pom中配置多個地址,只要統一配置group的地址就可以了右邊那個Repository Path可以點選進去,看到倉庫中artifact列表。不過要注意瀏覽器快取,當你的專案希望在多個repository使用資源時就不需要多次引用了,只需要引用一個group即可。
maven-public:maven-central、maven-release和maven-snapshot三個庫的合集。
maven-release:用來存放release版本的jar包。
maven-snapshot:用來存放snapshot版本的jar包。
關於Maven的Snapshot版本與Release版本
-
Snapshot版本代表不穩定、尚處於開發中的版本
-
Release版本則代表穩定的版本
-
什麼情況下該用SNAPSHOT?
協同開發時,如果A依賴構件B,由於B會更新,B應該使用SNAPSHOT來標識自己。這種做法的必要性可以反證如下:
a.如果B不用SNAPSHOT,而是每次更新後都使用一個穩定的版本,那版本號就會升得太快,每天一升e68a84e8a2ade79fa5e9819331333363396362甚至每個小時一升,這就是對版本號的濫用。
b.如果B不用SNAPSHOT, 但一直使用一個單一的Release版本號,那當B更新後,A可能並不會接受到更新。因為A所使用的repository一般不會頻繁更新release版本的快取(即本地repository),所以B以不換版本號的方式更新後,A在拿B時發現本地已有這個版本,就不會去遠端Repository下載最新的B
- 不用Release版本,在所有地方都用SNAPSHOT版本行不行?
不行。正式環境中不得使用snapshot版本的庫。 比如說,今天你依賴某個snapshot版本的第三方庫成功構建了自己的應用,明天再構建時可能就會失敗,因為今晚第三方可能已經更新了它的snapshot庫。你再次構建時,Maven會去遠端repository下載snapshot的最新版本,你構建時用的庫就是新的jar檔案了,這時正確性就很難保證了。
5、向 nexus3 私服上傳 jar 包
1、準備環境
1、建立3rd_part
庫
使用預設使用者 admin/admin123 登陸
點選左側的repository\repositories
後,在右側點選create repository
然後選擇maven2(hosted)
,填寫如下
跳到首頁後選擇maven-public
將3rd_part
移到member
中,即將3rd_part
由maven-public
管理,點選save
至此,建立倉庫完成
2、建立 3rd_part
管理使用者
建立使用者: 使用者名稱/密碼-dev/dev123
2、直接瀏覽器
使用dev/dev123
登陸,點選upload
填寫上傳jar包的資訊後,點選upload
可以看到已經上傳成功
4、常見錯誤
問題1:上傳報錯誤碼405,Failed to transfer file。
解決:仔細檢視報錯資訊就會發現,是上傳的url錯了,原因就是repository的地址寫錯了。
問題2:錯誤碼401或者403
解決:其實403錯誤就是“禁止訪問”的含義,所以問題的根源肯定在授權上面。Maven在預設情況下會使用deployment帳號(預設密碼deploy)登入的系統,但是關鍵的Nexus中Releases倉庫預設的Deployment Policy是“Disable Redeploy”,所以無法部署的問題在這個地方,方法是將其修改為“Allow Redeploy”就可以了。401就是Maven settings.xml沒有設定密碼