1. 程式人生 > >【區塊鏈】關於ETH/BTC區塊的監控

【區塊鏈】關於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