此次我寫的是一個小型的shell, 鏈接釘釘的機器人, 使用過的應該會比較嫻熟的了,下面就簡述一下把
主要的功能就是, 當發現本地數據庫區塊跟網絡上的區塊差距相差較大的時候就代表, 數據同步有問題, 這個時候, 發出一條告警出來,
對於比特網絡來說,我用的是https://blockchair.com/
注意到的哥們已經發現了, 在首頁的下方就是它的API, 我用的是比較愚蠢的方式去調用它, 直接用curl吧, 躁一把.
也可以點進去查詢它的相關調用, 這里面所調用的幣種也是換湯不換葯, 比如以下的, 就是取到指定幣種的網絡信息, 先拿下來分析一下把
https://api.blockchair.com/bitcoin/stats https://api.blockchair.com/bitcoin-cash/stats https://api.blockchair.com/litecoin/stats https://api.blockchair.com/bitcoin-sv/stats https://api.blockchair.com/dogecoin/stats https://api.blockchair.com/dash/stats https://api.blockchair.com/groestlcoin/stats https://api.blockchair.com/bitcoin/testnet/stats我
直接用curl了,取到信息了, 如下
但是有時候使用curl會給我彈出total這些渣渣字段, 很不喜歡, 所以, 發招用s參數吧, 以防萬一
curl -s https://api.blockchair.com/ethereum/stats
取到的數據很明顯了, 就是一個json格式的, 難道我還要去弄一個工具去格式化它? 非也
在linux中, 想必大家都知道,jq命令就能顯示格式化json, 如果沒有的話安裝一下
yum install jq -y
這樣就好辦很多了, 我們可以先把curl定義下來的東西重定向到一個文件中去啊, 然后用jq去分析那個文件不就行了嗎, 接下來數據就變成這樣了
[root@tx ~]# curl -s https://api.blockchair.com/ethereum/stats > block [root@tx ~]# jq ".data.blocks" block 9551780
你看, 直接取到網絡上最新塊的高度了, 但是, 為什么會這樣取呢, 其實用了jq之后格式是這樣的了, 用過的應該就很清楚
看, 活生生就是一個json, 我用的是.data.blocks, 就是直接把高度過濾出來而已.
那么接下來就是, 去取本地數據庫中的高度了, 我這邊用的是mysql, 直接就拿他開刀
[root@tx ~]# /data/tools/mysql -uroot -prkm2020 -S /tmp/mysql.sock -P 3306 -e "select cfg_val from db_config.tb_sysconfig where cfg_name='cache.usdt_erc20_sync_bcnum';" mysql: [Warning] Using a password on the command line interface can be insecure. +---------+ | cfg_val | +---------+ | 9519439 | +---------+ [root@tx ~]# [root@tx ~]#
看, 這就是我本地的高度, 但是, 如果你想拿這個9519439跟上面網絡上取到的高度去對比, 那么就不得不去掉mysql查詢格式出來的框框, 其實這里可以使用-N -s參數, 到底有什么用呢, 自行百度
[root@tx ~]# /data/tools/mysql -uroot -prkm2020 -S /tmp/mysql.sock -P 3306 -N -s -e "select cfg_val from db_config.tb_sysconfig where cfg_name='cache.usdt_erc20_sync_bcnum';" mysql: [Warning] Using a password on the command line interface can be insecure. 9519439 [root@tx ~]# [root@tx ~]#
看, 直接摳出來了, 上面還有一個提醒是吧, 其實不影響, 你直接把值取出來, 然后扔給一個變量去做對比, 是沒問題的
那么直接就看shell吧
這是一個完整的shell !
解析器在寫的時候可以自行添加.
currencyType="ethereum" MYSQL_CONN="/data/tools/mysql -uroot -prkm2020 -S /tmp/mysql.sock -P 3306 -N -s" N=0 function dingding(){ hostname=`hostname` webhook="https://oapi.dingtalk.com/robot/send?access_token=4db55f9cd1f96921acd6187d4431641e68bc39923d84d24fe0dbd" currTime1=`echo $(date +"%Y-%m-%d.%T")` curl ''$webhook'' \ -H 'Content-Type: application/json' \ -d '{"msgtype": "text", "text": { "content": " 服務器:'$hostname' 發生: '$currencyType'區塊數據同步異常! [ 提醒主機:'$hostname' 提醒信息: 區塊數據同步異常 監控幣種:'$currencyType' 進程同步區塊:'$local_height' 網絡最新區塊:'$netwo_height' 區塊差距:'$value' 提醒時間:'$currTime1' ] " } }' } function check(){ local_height=`$MYSQL_CONN -e "select cfg_val from db_config.tb_sysconfig where cfg_name='cache.usdt_erc20_sync_bcnum';"` curl -s https://api.blockchair.com/${currencyType}/stats > /tmp/netwo_height netwo_height=`jq ".data.blocks" /tmp/netwo_height` value=$[netwo_height - local_height] echo $(date +"%Y-%m-%d.%T"),$value if [ $value -ge 6 ];then dingding N=$[N+1] sleep 600; else N=0 fi } function main(){ while : do sleep 180; if [ $N == 0 ];then check else if [ $N -ge 2 ];then sleep 300; check else sleep 50; check fi fi done } main
首先, 我把幣種聲明變量扔在了文件的開頭位置, 下面就直接去識別, 就是這個
currencyType="ethereum"
需要監控其他的可以換成其他的, 比如bitcoin等
然后我為了偷懶, 把mysql的連接code, 塞進一個變量里面去, 為了下面方便調用它
dingding模塊應該沒什么好說的了, 檢查模塊, 無非就是拿出數據庫中的高度, 跟網絡上重定向分析出來的高度做對比, 用最新的高度減去本地區塊, 得出差距, 我這邊設置是在6個節點, 如果大於等於6, 那發個信息出來吧,
肯定有人疑問, N是什么鬼, N就是一個統計告警數, 為了不讓告警太頻繁
比如我下面的main的主體調用模塊, 3分鍾檢測一下,如果N等於0, 那就是說, 一切正常, 那么如果說, 發現了一次告警, 那么N+1, 發了一次信息, 等待10分鍾, 再檢測, 如果10分鍾后還是沒有恢復, 還來告警, 那么N再+1, 那就是跑了下面的大於或等於2的時候那個條件了, 再等待5分鍾然后再檢查, 如果說, 在這次死循環中, 告警過后恢復正常了, 然后N會被重置為0, 一切還是原來的模樣.
那么釘釘出來是怎么樣的呢, 這樣的
目的是什么, 主要是為了讓服務器本地環境與網絡上的區塊環境實現一致同步, 如果服務器的程序出現問題, 那么就能第一時間知道, 然后着手處理,
對於為什么不用golang去寫, 因為golang不會寫, bash更簡單, 但最不完美的就是, 可能死循環造成的資源消耗遠比golang小工具的多?
有待研究。
就到這里。