雖然在程式猿的世界裡流行乙個諺語」不要重複造輪子」。但是如果你開的就是一輛16寸輪轂的a級車,給你一副21寸的賓利輪轂你也是裝不上的。就算是運氣好找到了一副18寸的奧迪輪轂,可以正常的安裝並行駛,但是大輪轂所帶來的車速表不准,舒適度下降的問題又是不可避免的。所以適當的造造輪子也不失是一種節約後期維護成本的做法。所以從本篇開始,再次新開乙個章節–造輪子,跟大家聊聊關於造輪子的一些經歷。
在微服務平台中有些許多保證服務穩定性的方案。但是對於傳統主備,雙主的方案中,如何保證服務掛掉後能夠快速上線?守護程序就屬於一種價效比很高的方案。它占用資源小,對現有架構無改動。現在我們就在本篇中聊聊如何設計一款通用型的守護程序工具。
在設計守護程序之前,我們需要為我們所有待監測的服務新增service,並且需要service實現start,stop,status這三種指令。因為在我們設計的守護程序中是通過這這三種命令來改變服務的狀態的。
下面我們來描述一下整個守護程序的執行流程。
服務啟動以後,系統會初始化服務監測列表,將所有待監測的服務都新增至列表中。然後判斷監測列表是否為空,如果為空則停止守護程序。反之,繼續下一步。現在開始迴圈執行後面的步驟。間隔n秒後我們會迴圈監測每乙個服務,如果服務掛掉則連續最多n次嘗試拉起服務。如果服務被正常拉起則繼續迴圈監測下乙個服務,如果嘗試n次後也沒有拉起服務則將該服務從監聽列表中移出。因為如果服務多次嘗試都沒有啟動成功,那麼此時肯定是有什麼因素導致服務無法自動恢復,這時候就需要人工介入來排查問題恢復服務(其實這裡比較好的做法是當服務無法喚起的時候,通過**或者郵件的形式通知運維人員)。至此乙個監測迴圈結束,進入下乙個迴圈。
看完整個流程,現在我們來聊聊具體的實現,這裡我們採用shell來實現全部功能。
3.1 獲取服務列表
為了方便配置監聽的服務,我們將所有帶監聽服務的service名稱寫入配置檔案service.list
中
user
security
meeting
他們對應著/etc/init.d
中配置的service名稱。獲取服務監聽列表就可以這樣來寫
# 本地服務列表
localservice=`cat conf/service.list`
# 獲取監聽服務列表
function
getservicelist
()
簡單的通過檔案讀取命令cat
就可以獲取到待監聽的服務列表。
3.2 檢查服務狀態
#!/bin/sh
# 系統常量
# 服務執行標識
runflag='程序號'
服務檢測**如下所示
# 檢查服務狀態
# $1 service 名稱
function checkservice
()
3.3 服務的啟停
同樣,服務的啟動也是呼叫service的start和stop,實現**如下
# 啟動服務
# $1 service 名稱
function
startservice
() # 停止服務
# $1 service 名稱
function
stopservice
()
3.4 服務的喚起與移除監聽
讓我們先來看一下如何將服務從監聽列表中移除
# 從服務監聽列表中移除指定服務
# $1 待移除服務
function
removelistenserv
()
對於服務重試拉起的操作我們採用遞迴的方式,嘗試拉起的次數keepnexttime
我們也放在system.constant.sh
中進行管理。以下為重試拉起的邏輯
# 服務保活
# $1 service 名稱
# $2 service 剩餘restart 次數
function keepalive
()
這裡當重試次數為0的時候進入else邏輯,這時就會呼叫removelistenserv
介面將服務從監聽列表中移除
3.5 主控程式
至此服務的基本操作功能已經實現完畢了,此時我們需要來實現主控程式
## public function #######
# 守護程序啟動
function start
()
這段邏輯中主要就是檢視監聽列表是否為空和迴圈檢測服務狀態並保活。下面我們順道來實現一下守護程序的退出、執行狀態檢查和服務狀態檢查功能。
# 守護程序退出
function stop
() '|xargs kill -9
}# 檢視守護程序執行狀態
function status
() # 檢視服務執行狀態
function check
()
3.6 工具的啟動
既然叫做守護程序,肯定是要在後台悄悄的進行,所以我們需要實現乙個後台執行功能
function
start
()
其實這裡就是呼叫3.5主控程式中的status和start命令來實現
3.7 工具的安裝
既然守護程序的定位是乙個工具,那麼就一定要在任意路徑下都能執行的特點,所以這裡就需要將守護程序新增至service中
# 新增service
# $1 servicename
function addservice
()
由於守護程序本身也是脆弱的,可能會隨時掛掉,所以我們可以將其新增至系統的定時任務中
# 新增定時任務
# $1 定時任務間隔時長
function
addcrontab
()
到這裡工具的主要邏輯已經講解完畢了,現在讓我們來看看工程的完整結構
daemon:.
│ daemon.sh ---- 工具的主控部分
│ setup.sh ---- 工具的安裝部分
│ start.sh ---- 工具的啟停控制部分
├─conf
│ service.list ---- 服務監聽列表
├─constant
│ system.constant
.sh ---- 工具的配置資訊
├─lib
│ date.lib
.sh ---- 日期庫
│ log.lib
.sh ---- 日誌庫
│ pkg.lib
.sh ---- 安裝庫
│ show.lib
.sh ---- 控制台顯示庫
└─service
check.service
.sh ---- 服務的基本操作部分
5.1 工具安裝
5.2 工具的啟動
5.3 服務狀態的檢視
該機器下面並未安裝這幾個服務,所以會提示service不存在
5.4 檢視日誌
造輪子 python手動實現OTUS
最近研究閾值化演算法,otus算是目前應用比較廣泛的,自己想實現otus看和opencv對比,哪個用時短 最後經numba加速後還是失敗,opencv的otus演算法速度是自己手寫的轉換速度的5 10倍。果然現成的輪子是比較好用的 otus法又稱最大類間方差法或者大津法,基本思想就是計算前景類與背景...
造輪子 補碼實現與若干分析
這周計算機原理課收到樓sir的乙個作業 要自己實現一套整數編碼的數碼轉換與若干運算,並分析。我拿到的是補碼,其他的隊友分別要實現一套原碼 移碼或者自行設計一套 帥碼 666 程式語言 c 聽說規定要用c語言造這個輪子,真是遺憾,要是c 還可以各種運算子過載可以很優雅。那好吧,在編碼之前,先做個約束。...
造輪子 toast元件的實現 下
1.解決 toast 中傳入 html 的問題,通過假的 slot 來實現 plugins.js toast.slots.default message toast.vue 使用 created 2.在 toast 中加 html 是比較危險的乙個動作,所以要加乙個選項預設不開啟。toast.vue...