【區塊鏈】關於ETH/BTC區塊的監控
此次我寫的是一個小型的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小工具的多?
有待研究。
就到這裡。
&n