1. 程式人生 > >我是如何重構整個研發專案,促進自動化運維DevOps的落地?

我是如何重構整個研發專案,促進自動化運維DevOps的落地?

為了這篇文章,我前後寫了將近十篇文章鋪墊,才將這篇整體重構思想引出。

背景

先說下背景,我們是一家小公司,雖然打著做產品的旗幟,但是每個客戶都有大量的個性化功能,這裡指各個客戶的java端、Android端、ios端(大部分功能程式碼是相同的,個性化功能程式碼不同)。我之前是做Android的,實踐證明,特殊情況下,只有我們Android組可以隨意切換到任意一家客戶,任意一版本的程式碼。並且修復一處公共bug,所有客戶的版本都會更新。我也一直在介紹這種開發模式,但並得不到支援,直到年初,我晉升為移動端組長,加上,後來java組組長跳槽,我才有機會全面實施重構計劃。

前言

因為我做過很多年的運維(網咖軟硬體運維等),對伺服器硬體以及軟體有較高的認識,加之我對各門語言有一定的開發經驗,算是一位全棧工程師,對各端都比較熟悉。這一切,為我的實施帶來了很大的幫助。
本人申明以下所有重構思路均出自本人想法,實施上,由我統一安排培訓後落實。(雖然落實阻力極大,但最終效果不錯)

先說說效果

之前,我們每接入一個客戶專案,完成java端、Android端、ios端和部署伺服器環境等,需要2周的時間。現在,我們大概需要30分鐘。並且每位客戶個性化需求再多,我們也能靈活開發及切換到各個客戶的程式碼上。
之前,我們開發流程極為混亂,沒有文件,沒有各種開發流程,現在我們逐漸規範,至少節約50%的開發成本。當然,我們還在不斷改善中。

java專案組

我們的java專案,原來分為介面服務、後臺管理服務,但是都在一個git庫裡,我將它分為:
1. 介面服務
2. 後臺服務
3. html5包
4. 公共包服務

因為本次重構,我逐步採用前後端分離方案,所以多出了h5包。

每個庫分為多個分支,其中定義master為主分支,各個客戶為新開的一個分支,通過分支來解決各個客戶各種不同需求,(因為客戶需求實在過細,有些文字都得改,單純的外掛化開發的話,每個外掛都要n多個版本,這樣對於我們小公司,做不起來),當然各個客戶也應該有個開發分支,但受限於我們人員較少,一期省去了開發分支,把本地暫存區作為開發分支。
關於如何在不同分支開發,可參照我另外一篇文章
《你確定你能記住那麼多的git命令嗎?快試試Sourcetree吧》

開發流程如下:

開發人員只需要本地除錯後,提交程式碼到git庫的某個專案分支上,由Jenkins自動編譯,關於Jenkins自動編譯全端專案可參照我另外一篇文章

某小型公司持續整合工具jenkins實踐(JAVA WEB、Android、IOS、html)
如果編譯錯誤會通過郵件反饋到影響程式碼的開發人員郵箱中,另外測試人員一鍵部署後,測試出問題,也可以通過jira提單給開發人員。開發人員收到後,繼續提交程式碼,不再像我們之前,必須通知開發人員,開發人員本地打包,這樣無法跟蹤專案程式碼。

補充:
因為我們專案比較多,人為維護版本號會費時費力,我決定一期採用Jenkins自動填入版本號到專案中,並在檔名中體現,所以,專案編譯出的包可能是1.war、2.war、3.war,我們內部將其(1、2、3)作為版本號,當然war包內部我也寫入了版本號。
其次,我們剔除了大量含狀態的程式碼,使得每個war在測試環境和生產環境自動載入不同配置來執行,因為無狀態,所以war包、h5包在測試環境和生產環境都是一套程式碼。這裡我們花了幾周時間完成抽取無狀態程式碼。

一鍵部署:
我們做了一套管理平臺,可升級tomcat中介軟體下的各個war和h5,相關介紹見我另外一篇文章
java web專案war包自動升級部署方案
可以看看我們現在的效果:

主要功能如下:
1. 升級、顯示當前版本
2. 對war包有效期,真實性校驗
2. 開發人員將公共sql放入公共.sql裡
3. 各個客戶定製化需求的sql放入各個客戶.sql裡

每次只需要點後面的升級按鈕,即可升級sql指令碼或服務。
文章是之前寫的,邏輯上有些變化,這裡不做介紹。

客戶端組

客戶端開發流程,這裡ios和Android一起說,我們提交程式碼後,Jenkins都會同時生產兩套連線伺服器地址不同的ipa、apk,這裡因為很多情況在不同網路環境下需要看測試環境和生產環境,所以,我採用同時發2套包方案。

Android的同時2套包方案可參照我之前
Android利用gradle同時編譯多包(測試環境地址、生產環境地址)
IOS同時發2套ipa包方案可參照我之前的
IOS利用Xcode同時編譯多包(測試環境地址、生產環境地址)
在ios上架appstore流程上,我採用了半自動化發包策略,將其上傳到開發者平臺後,手動上架。
各個客戶,各個版本我們採用多分支的方案,和上文java同理,不同分支處理不同客戶專案。

測試組

測試組流程


測試人員從jira提單後,開發人員解決後,會看到具體解決的版本號,然後進入oss儲存,安裝Android程式,或者ios程式,一鍵部署java專案。
而因為安卓和ios均是同時發2個包,java專案、h5專案無狀態,所以生產環境和測試環境都可快速部署測試。
圖中,以real檔名結尾的是連線生產環境地址。

專案經理

專案經理流程


我採用新客戶新流程,老客戶老流程,並逐步遷移到新流程中。
其中執行資料庫指令碼已經被省略,由統一部署平臺執行。

運維組


這張圖是以前的邏輯,因為每個時期,每個客戶給的伺服器和伺服器系統各不相同,運維起來極為複雜。我採用docker容器統一方案解決此問題,使得每個客戶機器環境均相同。
下圖我是我解決後的模型圖:


我們把各個客戶的伺服器都整成docker叢集,然後通過我們公司統一管理平臺管理,然後將各個容器分配給不同的角色,這裡我們是用Portainer來解決,並二次開發了一些需求。
詳細可看我另外一篇文章
Docker的web端管理平臺對比(DockerUI 、Shipyard、Portainer、Daocloud)
這裡的管理都不需要linux機器的密碼,通過tls證書進行控制,而Windows機器將廢棄不用。

該方案優點:
1. 在docker下,所有客戶生產環境相同。
2. 易於備份、遷移、恢復。
3. 可建高可用環境,發包時採用灰度發包,藍綠部署不中斷服務。
4. 可支援彈性伸縮設計,支援擴充套件。
5. 支援負載均衡,域名轉發,意外切換容器等。
6. 有利於轉型微服務架構。
7. 快速搭建環境

而建立docker叢集需要我們自動化完成,這裡我採用了Ansible工具來實施,我們可通過指令分發,指令獲取所有機器某個包的版本,執行不同的程式碼。
詳細參照我另外一篇文章:
自動化運維工具ansible的實踐

然後通過image映象對客戶進行統一部署容器,這裡我們建立了私服。

私服篇

這裡我建立了各種倉庫,方便java開發,我建立了一個私有倉庫,一個maven官方代理倉庫,一個阿里雲代理倉庫;
docker上我為了方便開發打包其他環境,我建立了docker私有倉庫;
還有一些為了解決統一管理linux伺服器而建立npm倉庫;
以及安卓所要使用的gradle私有倉庫;
未來,我可能還會建立更多倉庫,能支援的倉庫列表都在下面:

大資料篇

大資料一直以來是很多公司核心產品,對於小公司,如何低成本實施呢,我研究了一套強大的大資料框架,並對其做了部分的二次開發。
詳細可參照另外一篇文章
https://juejin.im/post/596702f7f265da6c23289373
放心吧,只要你用了這個框架,一定可以輕鬆解決各種大資料圖表問題。

介面篇

我全面統一採用restful風格api開發介面,介面文件自動生成,這裡涉及幾篇文章,暫時還沒來得及寫,後續補上。

規範篇

我還制定了一些規範和約定,比如內部開發協作等約定,暫時還沒寫完,後期我也會補上。

文化篇

之前,我們開發需求完全依靠專案經理分配,現在我安排不斷重構專案,帶來了很多新的流程,這裡徵得領導同意,安排每週或每2周分別對各部門,培訓後分配賬號,實施。這個涉及公司內部業務,不便詳說,敬請諒解。

DevOps的落地

DevOps這個詞,是我上次在上海CNUTCon全球運維技術大會2017會上所知,我才知道大部分公司都在做自動化運維,縮減運維工作。
關於這方面,我也寫了2篇文章,可參照
[Day 1]上海CNUTCon全球運維技術大會2017實錄
[Day 2]上海CNUTCon全球運維技術大會2017實錄
在文章中,我融入了不少自己的想法。
當然,適合我們公司DevOps的落地方案已經實施一大半了,剩下的我還在努力設計藍圖中。以後一定會和大家分享。

後續

我寫了幾個月各方面的文章,大部分讀者可能以為我是胡寫一通。今天,終於把他們匯聚到一起,說實話,心情還是蠻激動的。

我承認我所有的重構對於很多大公司都是提不上臺面的,但對於我們小公司,很多東西形成體系,說實話,真的很難。還有些內容,我不方便說,或者是忘記了說。事實上,我們做的遠比文章裡的內容要多得多。
還有,部分文章可能是幾個月前寫的,邏輯上和流程上,我們都已經做了很多優化和調整,但是主體思想都沒有變,不影響閱讀。

其次,我申明,本文中所有介紹,絕對不是最好的解決方案,很多方案是我對公司進行分析後定下的,絕不是每個小公司都適合。但我覺得本文一定能給你帶來不少的靈感。

最後,本人能力有限,開發圈子也比較小,難免有考慮不周的地方,如果您有任何高見,歡迎告知,小生在此謝過大家。