2017年10月9日 星期一

Raspberry Pi 3 的系統監控與自製散熱解決方案

通常樹莓派都是以 Headless computer (沒有外接螢幕與鍵盤滑鼠)的方式運作,而用作家庭物聯網(IoT)伺服器、監視器主機或是檔案伺服器的情況也是一樣,通常都是把樹莓派放在一些比較難以觸及或看到的地方,可能掛在高處,也可能放在數據機旁邊

而這種應用環境會出現一些運用上的問題,像是最常見的散熱與系統運作問題,首先講一下散熱問題

Raspberry Pi Model B 來說,採用的 BCM2835 SoC 在待機溫度上已經達到了 48.7°C,滿載溫度也有 55.7°C,負責 USB 埠與網路功能的 LAN9512 也可以達到 62.4°C 的高溫,在長時間的運作下可能會出現運作緩慢甚至當機的情況,因此要在晶片上黏貼散熱片,並視情況加上風扇去排出累積的熱量

下面就是各種嘗試過的散熱方案


2017_09_02_170830
一開始就有在背面的記憶體顆粒貼上散熱片
2017_09_02_170800
系統晶片 BCM2837 SoC 與負載時散發高溫的 LAN9514 也有貼上
2017_09_04_124840
省略上蓋直接放進自製支撐架
2017_09_13_020040
想加裝風扇所以弄了自製支撐架第二代
2017_09_13_020310
使用一顆六公分的風扇,驅動電壓五伏特的特規品
2017_09_13_111910
結果風量是有了,但風切聲很大,到了沒有安裝護罩都很吵雜的程度
2017_09_15_222428
只好再弄了自製支撐架第三代,改用九公分風扇
2017_09_15_222446
一開始採購的轉接線太長要繞著支撐架內部
2017_10_05_010054
改用自製轉接頭之後就可以直接接上

散熱問題解決之後,再來是軟體跟系統上的監控,你可以使用一些自動化腳本來監控,並在發生異常時提醒你去處理,當然樹莓派內建的硬體看門狗也是必須的,安裝看門狗之後可以在系統負載異常、處理器溫度過高、網路流量異常時重新啟動,端看你怎麼去設定監控函數

而我也額外寫了一些基於 Python 的小程式來監控,並使用 Crontab 來達成自動化運作,並在異常時通知我,我把撰寫好的程式放在 GitHub 上,Suzhou65/RaspberryPi-Automatically-Report


2017_10_05_192647
透過 Crontab 就可以讓這些基於 Python 的小程式自動運作
2017_10_05_193028
在排程好的時間就可以自動寄出系統溫度報告,並且在指定程式異常時發送通知(這是示範

再來講一下如何達成自動監控指定程式

在 Linux 系統中有所謂的 ps 指令,可以列出運作中的程式與系統程序,而透過調整參數,可以取出你想要的結果,再加以過濾,並搭配判斷式,就可以做出一定的操作

當然這邊是去查詢定程式是否在系統層面上正常運作(沒有當機或是凍結),如果是程式內部錯誤可能沒辦法偵測


2017_10_08_000953
簡單示範,輸入 ps x 可以看到運作中的程式與細部狀態
2017_10_08_001137
添加 grep 可以篩選出指定的程式
2017_10_08_001626
撰寫成 Python 腳本並搭配 awk 指令可以擷取指定輸出
2017_10_08_001641
這樣只會輸出指定程式的執行狀態與我想要的額外資訊
2017_10_08_001715
再加上一些替換子來去掉我不要的字符
2017_10_08_001735
就會輸出過濾後的字串
2017_10_08_001818
再加入判斷式去檢查是不是有符合我指定的字串
2017_10_08_001839
符合的話就會輸出這樣的結果

上面的範例是為了偵測 Hentai@Home 這套分散式運算系統是不是運作正常,因此我只要針對 HentaiAtHome.jar 這個程式作監測就好,將剛剛的判斷輸出改寫成電子郵件發送,就可以在偵測到異常時回報給我,並附上用於檢測的輸出結果來讓我判斷是不是真的有問題,還是說單純的誤報

只要輸出結果是 Sjava 則代表程式正常運作中,輸出 Sgrep 則是程式不在運作,其餘輸出則是程式當機或是凍結


2017_10_08_002738
這邊稍微修改一下判斷式,所以會把正常的狀況判定成異常並且回報
2017_10_08_002841
執行那個 Python 腳本就會輸出這樣的結果

理論上這樣就可以去偵測異常了,但我在兩個禮拜的運轉中有時會收到虛假的異常回報,顯示程式不在運作,但去檢查 Hentai@Home 頁面卻是正常的,因此做了一點研究

2017_10_08_215444
有時會收到這樣的異常回報,但程式其實是正常的

結果似乎是有時第一行輸出跟第二行輸出的順序會反過來,而 awk 只會抓取第一行,導致判斷式認為發生異常

而解決方法很簡單又暴力,直接兩行一起輸出再過濾跟判斷就好


2017_10_08_220309
將 awk 函數改成兩行都抓取,用替換子去掉我不要的字符後輸出
2017_10_08_220502
在替換子中去除換行字符
2017_10_08_220657
在讓判斷式去搜尋 Sjava 就好
2017_10_08_220646
執行 Python 腳本就會輸出這樣的結果,再把判斷輸出改寫成電子郵件發送就好