發佈系統有那麼難麼?

更多精彩文章。前端

《微服務不是所有,只是特定領域的子集》vue

《「分庫分表" ?選型和流程要慎重,不然會失控》java

這麼多監控組件,總有一款適合你python

《使用Netty,咱們到底在開發些什麼?》git

《這多是最中肯的Redis規範了》程序員

《程序員畫像,十年沉浮》github

最有用系列:web

《Linux生產環境上,最經常使用的一套「vim「技巧》npm

《Linux生產環境上,最經常使用的一套「Sed「技巧》bootstrap

《Linux生產環境上,最經常使用的一套「AWK「技巧》


必要性

若是一個上點規模的公司,技術團隊有什麼值得一作的系統,那麼發佈系統算一個。 jenkins用的好好的,爲何要本身搞呢?總結下來,有下面幾點緣由:

一、 每一個公司的流程和技術棧都是不同的,生搬硬套,就像便祕同樣不暢。

二、 發佈系統技術開發成本不高,很容易搞。你要是以爲難搞,那必定是卡在複雜的公司人員環境和流程上。

三、 jenkins這樣的工具要想作個加強功能,不比本身開發簡單。好比加個審批環節,作個表單嵌入什麼的。

一句話,本身搞個套餐不比改造現成的難。

概要

開發一個發佈系統是很簡單的,雖然須要全棧的知識(前端、後臺、腳本)。有多簡單呢?咱們提供了兩我的力,只花了10個工做日就所有完成了。看完本文,你要是以爲不簡單,那就是咱們太牛掰了(囧),畢竟也是見識過七八個高開去作一樣事情的豪華陣容。

流程上是幫不了你什麼忙了,但在技術上,我將奉上我的以爲很不錯的一套實現。若是你的架構是基於SpringCloud的,你會發現很貼心。發佈系統主要有如下功能:構建模塊、部署模塊、權限管理模塊、審計模塊

構建模塊

用戶登陸系統後,會看到全部擁有權限的項目列表。點點擊前往,則進入構建頁面。

構建模塊實際上是很是簡單的。不論你是用 maven,仍是 gradle,再或者 cnpmg++等,都是經過傳入一堆參數到腳本中執行。在這裏推薦使用 python腳本進行更多控制。

構建者能夠選擇任何一次提交進行構建。構建成功後,會自動給提交打tag(也能夠自定義tag)。同一個項目不容許同時打包。構建失敗,能夠從新進行構建,構建者會看到實時滾動的日誌。這裏有兩個技術點:

1) 如何獲取git的提交記錄並進行切換?

2) 如何顯示滾動日誌?

獲取gitlab的提交記錄

拿gitlab來講(由於用的最多)。加入gitlab的maven便可使用。

<dependency>
    <groupId>org.gitlab</groupId>
    <artifactId>java-gitlab-api</artifactId>
    <version>4.1.0</version>
</dependency>
複製代碼

獲取最近提交記錄。

api.getAllCommits(projectId,page, branch)
複製代碼

打tag

api.addTag(projectId, tagName, hash, tagTitle, tagContent);
複製代碼

滾動日誌實現

見本公衆號文章《滾動日誌的實現》

部署模塊

不少發佈系統讓人很不爽的一點,就是不支持單臺或者多臺發佈,不方便並且風險大。

部署頁面只顯示已經打包成功的記錄,按照提交時間倒序顯示。支持從新部署,不論是上次部署成功仍是失敗。部署界面以下:

點擊部署按鈕,便可顯示部署機器列表,能夠選擇一個或者多個進行部署。
部署記錄都會按照打包記錄進行分組,顯示在日誌列中。同一次部署,若是有一臺部署失敗,則默認部署總體部署失敗,能夠從部署日誌判斷當前的部署狀態。

能夠看到系統實際上是沒有回滾的概念的,只有部署哪一個版本的概念。一個服務可能有上百臺機器,如何更優雅的顯示多版本共存的關係,有條件的團隊是不會放過這個改進的。

SpringCloud的部署過程

權限管理

github上有不少開源的實現,隨便搬弄一套集成便可。咱們主要談一下權限理念。

權限設計有兩個要點。第一不能阻礙研發的開發效率,第二要嚴控線上的安全。因此線上和非線上環境是分開設計的。

1) 一個系統的用戶,要麼是超級管理員(就是神馬都能幹的那總);要麼是帶有線上權限標識的用戶;再就是普通用戶了。

2) 一個用戶,要麼是某個項目的成員,要麼不是

權限圖以下:

操做都會被記錄進操做歷史,而且發送郵件(或者其餘hook):

1) 修改項目,發送給項目成員全部人

2) 構建項目,發送給構建者構建結果

3) 部署項目,發送給項目成員全部人

全部的操做記錄,在項目中均可查。

腳本

發佈系統的web端,不過是套層皮囊。真正去執行的,仍是咱們的腳本。

使用python腳本進行構建和發佈,是很是方便的。有些java開發人員對腳本不是很熟,我這裏挑比較重要的點說明一下。

執行過程顯示

建議使用logging模塊控制。效果見下圖。

import logging

def setup_logging():
    root = logging.getLogger()
    root.setLevel(logging.DEBUG)
    ch = logging.StreamHandler(sys.stdout)
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)
    root.addHandler(ch)
複製代碼

腳本異常記錄

默認python執行異常是不輸出到stdout的,咱們須要強行轉換一下。

import sys
import traceback

try:
    setup_logging()
    #...
except Exception as e:
    exc_type, exc_value, exc_traceback_obj = sys.exc_info()
    traceback.print_exception(exc_type, exc_value, exc_traceback_obj, limit=2, file=sys.stdout)
複製代碼

遠程執行

發佈系統的機器應該都作了免密登陸。經過 ssh -t "su - sth" 能夠切換到任何一個用戶在遠端執行程序。 但實踐證實,經過python的subprocess模塊執行存在諸多問題。因此咱們才用了paramiko庫進行了遠程調用。

s = paramiko.SSHClient()
s.load_system_host_keys()
s.connect(srv, 22 )
(stdin, stdout, stderr) = s.exec_command(cmd)
last_line = ""
for line in stdout.readlines():
    last_line = line
    print( line)
    s.close()
複製代碼

安全的殺死進程

你們都應該知道kill -15kill -9的區別。如下腳本讓程序等待10秒,而後使用kill -9殺掉她。

注意:如下腳本有巨坑~,必定要傳參

n=0
while [[ $n  -lt  10 ]]
do
    let "n++"
    ex=`ps aux|grep \/${flag}|grep -v grep | grep -v sc. | awk '{print $2}' `
    echo $ex
    if [[ $ex == "" ]]
    then
        echo "program not exist"
        break
    else
        echo "send kill -15 to below:"
        echo $ex
        ps aux|grep \/${flag}|grep -v grep | grep -v sc. | awk '{print $2}' |  xargs kill -15
        sleep 1
    fi
    if [[ $n  -eq 10 ]]
    then
        # after 10s , try to send kill -9
        ps aux|grep \/${flag}|grep -v grep | grep -v sc. | awk '{print $2}' |  xargs kill -9
    fi
done

##start jar
echo "start jar"
nohup  -jar $jar  >/dev/null 2>&1 &
echo "restart ${flag} !!!"

sleep 2
ex=`ps aux|grep \/${flag}|grep -v grep | grep -v sc. | awk '{print $2}' `
if [[ $ex == "" ]]
then
    echo "Fail"
else
    echo "new PID is "
    echo $ex
    echo "OK"
fi
exit
複製代碼

前端

vue幹這個大材小用了。咱們選擇了後臺都熟悉的bootstrap,配上一個比較古老好看的AdminLTE框架。

但這麼多頁面寫起來也是很是浪費時間的,因此咱們也集成了ejs模版引擎。

對技術團隊的建議

1) 要信得過本身團隊,信得過本身。若是公司環境複雜。少開會去討論,少扯皮。先閉關鎖國再改革開放。先閉門造車,作出個東東來,再讓各位大爺們品頭論足,進行修改。畢竟也花不了多長時間,原型驅動再好不過了,你又不是一次性作個百分項目。

2) 設計時必定要考慮項目類型的多樣性和分佈式。別等着需求來了,量來了,把你連根拔起。

3) 自動化雖然好,也要準備好應急的手動化方式。若是CTO親自給你來電了,這並不見得是一件好事。

相關文章
相關標籤/搜索