團隊在開發流媒體服務,須要實現一個監控在線人數的功能,能夠看到歷史有多少人在線,當前有多少人在線的功能。
若是用mysql等關係型數據庫來實現,能夠用事件記錄日誌,而後經過PHP加上一些繪圖的插件來實現,但這種方式並很差,首先用關係型數據庫隨着時間累積,會存在數據量愈來愈大,致使查詢緩慢,再者須要編寫這部分統計代碼,所以並非最佳選擇。php
咱們很快找到了一個「時序性數據庫」(prometheus),這種數據庫會以時間節點來記錄咱們要存儲的數據,而後結合他的一些繪圖功能,咱們徹底能夠不用寫繪圖的邏輯,並且prometheus還提供數據收集的功能,咱們只須要把須要統計的數據按照固定的格式傳遞就行了。而Grafana是一個專門繪圖的,支持不少種數據源,好比mysql,prometheus,es等數據庫,繪圖功能特別強大,所以咱們便使用了這兩種軟件的結合實現了一個監控功能。mysql
兩個工具都是英文的,若是英文和我同樣不怎麼好,建議使用谷歌瀏覽器的網頁翻譯功能,能夠節省不少時間sql
操做步驟:docker
官方安裝文檔:https://grafana.com/grafana/d...數據庫
brew install grafana
docker run -d --name=grafana -p 3000:3000 grafana/grafana
官方安裝文檔:https://prometheus.io/docs/pr...api
在安裝以前咱們先創建好配置文件,讓安裝後能夠直接啓動,配置文件的模板在官方文檔中有,下面是我使用的配置文件,也能夠直接使用,記得把配置文件的(#後面的內容刪除)瀏覽器
--- global: #全局配置 scrape_interval: 5s #5秒鐘收集一次數據 scrape_timeout: 3s #鏈接超時時間 scrape_configs: #子配置 - job_name: 'media' # 任務名稱爲media scrape_interval: 3s # 3秒鐘收集一次數據 metrics_path: "/api/v1/rrd/metrics" # 收集數據的URI static_configs: #子項配置 - targets: ['gslb.offcncloud.com:8080'] #收集數據的目標主機以及端口
brew install prometheus
(注意配置文件得咱們先建好才能運行下面的命令)微信
docker run -p 9090:9090 -v /tmp/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
在第一步咱們安裝prometheus的時候就創建了一個配置文件,其中有一個任務會去收集數據,主機名爲(gslb.offcncloud.com:8080),URI地址爲(/api/v1/rrd/metrics),所以會不斷向 http://gslb.offcncloud.com:8080/api/v1/rrd/metrics 進行請求,來獲取數據。網絡
這個時候咱們須要來了解這個數據的格式是怎麼樣的,先來看一段我返回的數據格式。工具
media_network 2 media_connectNum 12 media_on_push 2
在上面有三行數據,每條數據分別表明不一樣的key => value ,中間使用空格隔開。
好比:
上面的這寫數據是怎麼得來的呢?其實咱們的系統當中並不能直接獲取到當前的數量,好比鏈接人數,可是咱們能夠經過一些日誌或者事件來進行統計,好比當有一我的播放視頻,那麼咱們將會在cache中給他+1,當他離線的時候咱們則會給他-1,這樣即可以獲得數量,咱們能夠來看下下面的僞代碼
事件觸發計數的代碼部分
<?php /** * 計數 * @param string $name network|connectNum 要統計的名稱 * @param bool $type 上線仍是離線 * @param bool $clean 是否每次清空 * @return int|string */ public static function count(string $name, $type = true { //定義名稱 $name = addslashes($name); $fileName = self::BASEDATA . $name ; //定義累加值 $addNum = $type ? 1 : -1; //更新次數 $num = "cat $fileName"; $num = intval(exec($num)) + $addNum; //鏈接數不能小於0 $num = ($num < 0) ? 0 : $num; $cmd = "echo $num > $fileName"; exec($cmd); return $num; }
prometheus來收集數據的對應代碼部分
public static function getCountNum() { $control_arr = ['network', 'connectNum', 'on_push']; self::createDir(); foreach ($control_arr as $path) { //存放臨時數據文件 $tmp_file = self::BASEDATA . $path; $num = exec("cat $tmp_file"); switch ($path) { case 'network'://網絡延時數量 system("echo 0 > $tmp_file"); echo "media_{$path} $num" . PHP_EOL; break; case 'connectNum'://鏈接數 echo "media_{$path} $num" . PHP_EOL; break; case 'on_push'://推流數 echo "media_{$path} $num" . PHP_EOL; break; } } }
在計數部分代碼會根據用戶是上線仍是下線來處理不一樣的邏輯,好比上線數量會+1,下線則會-1
在獲取數據部分,會根據不一樣的類型來處理他的邏輯,好比網絡延時數量,會在獲取數據後清空爲0,而鏈接數則不在這個位置進行清空
通過前面兩個步驟,若是是docker安裝應該已經啓動了,若是是mac安裝啓動命令爲(注意配置文件路徑):
prometheus --config.file=/tmp/prometheus.yml
當啓動以後,能夠打開瀏覽器訪問以下URL地址:
http://127.0.0.1:9090/targets
如上圖,上面沒有綠色的說明鏈接地址配置成功了,此時prometheus會不斷的收集數據
接着要驗證數據格式是否正確,打開URL地址
http://127.0.0.1:9090/graph?g0.range_input=1h&g0.expr=&g0.tab=0
若是能看到咱們在代碼裏面返回的key,便說明數據收集對接成功了
繪圖時候咱們採用Grafana來進行,所以咱們首先得啓動它,若是使用docker安裝時,此時應該已經啓動起來了,若是是mac系統的brew安裝,啓動命令爲
brew services start Grafana
在啓動以後,咱們打開瀏覽器,訪問URL地址爲:
http://192.168.43.34:3000/
能夠在界面中看到登陸框,默認的帳號以及密碼爲 admin admin
進來以後首先須要進行配置數據來源,數據源的配置以下圖
點擊保存按鈕,進行保存並驗證,若是沒有提示異常說明已經成功了。
如今已經有數據源了,那咱們須要把這些數據展現爲圖表就很簡單了,點擊頁面中很明顯的+號,建立儀表盤,選擇graph,以下圖
接着變回出現一個圖表,可是沒有任何效果,因此咱們須要編輯這個走勢圖,以下圖所示
接着下方便會出現圖表的配置項,這裏咱們能夠選擇數據源,以下圖
選擇數據源以後,咱們須要選擇使用哪個字段,並把這個字段改成設置一箇中文名稱,同時這裏能夠設置多個字段,以下圖
配置好以後必定要保存!
查看效果
限制咱們將能夠看到效果,以下圖
做者:湯青松微信:songboy8888