我是這樣重構整個研發項目,促進自動化運維DevOps的落地?

  • 2019 年 12 月 24 日
  • 筆記

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

背景

先說下背景,我們是一家小公司,雖然打着做產品的旗幟,但是每個客戶都有大量的個性化功能,這裡指各個客戶的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庫的某個項目分支上,由Jenkins自動編譯。

如果編譯錯誤會通過郵件反饋到影響代碼的開發人員郵箱中,另外測試人員一鍵部署後,測試出問題,也可以通過jira提單給開發人員。開發人員收到後,繼續提交代碼,不再像我們之前,必須通知開發人員,開發人員本地打包,這樣無法跟蹤項目代碼。

補充:

因為我們項目比較多,人為維護版本號會費時費力,我決定一期採用Jenkins自動填入版本號到項目中,並在文件名中體現,所以,項目編譯出的包可能是1.war、2.war、3.war,我們內部將其(1、2、3)作為版本號,當然war包內部我也寫入了版本號。

其次,我們剔除了大量含狀態的代碼,使得每個war在測試環境和生產環境自動加載不同配置來運行,因為無狀態,所以war包、h5包在測試環境和生產環境都是一套代碼。這裡我們花了幾周時間完成抽取無狀態代碼。

一鍵部署: 我們做了一套管理平台,可升級tomcat中間件下的各個war和h5。可以看看我們現在的效果:

主要功能如下:

  1. 升級、顯示當前版本
  2. 對war包有效期,真實性校驗
  3. 開發人員將公共sql放入公共.sql里
  4. 各個客戶定製化需求的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來解決,並二次開發了一些需求。

這裡的管理都不需要linux機器的密碼,通過tls證書進行控制,而Windows機器將廢棄不用。

該方案優點:

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

而建立docker集群需要我們自動化完成,這裡我採用了Ansible工具來實施,我們可通過指令分發,指令獲取所有機器某個包的版本,執行不同的代碼。

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

私服篇

這裡我建立了各種倉庫,方便java開發,我建立了一個私有倉庫,一個maven官方代理倉庫,一個阿里雲代理倉庫;

docker上我為了方便開發打包其他環境,我創建了docker私有倉庫;還有一些為了解決統一管理linux服務器而創建npm倉庫;

以及安卓所要使用的gradle私有倉庫,未來,我可能還會創建更多倉庫,能支持的倉庫列表都在下面:

大數據篇

大數據一直以來是很多公司核心產品,對於小公司,如何低成本實施呢,我研究了一套強大的大數據框架,並對其做了部分的二次開發。

接口篇

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

文化篇

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

後續

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

我承認我所有的重構對於很多大公司都是提不上檯面的,但對於我們小公司,很多東西形成體系,說實話,真的很難。還有些內容,我不方便說,或者是忘記了說。事實上,我們做的遠比文章里的內容要多得多。

還有,部分文章可能是幾個月前寫的,邏輯上和流程上,我們都已經做了很多優化和調整,但是主體思想都沒有變,不影響閱讀。

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

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

作者:邵磊 鏈接:https://juejin.im/post/59e1d92d51882578db27c2e1