天天看點

實戰Pinba

誰都知道監控系統很重要,但是要自己搭建一套好用的系統卻不是一件簡單的事情。國内已經有不少廠商提供類似的服務,比如:OneAPM、聽雲,其原理就是通過在伺服器上部署一套探針,把資料彙總上報,但是問題卻不像說起來這麼簡單,我曾經買過國内某個廠商高大上的 APM 服務,誰知道它監控的名額太多了,并且無法自定義,結果導緻一上線,系統性能就下降百分之二十,最後無奈隻好放棄。

我想要的是一種對系統性能影響盡可能小的監控系統,它不需要監控太多名額,隻要有 RPS、CPU、記憶體、響應時間等幾個核心資料即可,而 Pinba 簡直就是為此量身打造的:PINBA(PHP Is Not A Bottleneck Anymore)原本是 PHP 專用的,其工作原理大緻是:在每個請求處理完成後,PHP 把相關資料通過 UDP 發送給 Pinba 自定義的 MySQL 引擎。因為資料是通過 UDP 傳輸的,是以對原有系統的性能影響很小。如果非要說說 Pinba 的缺點,那麼它沒有提供一個官方的 UI 算一個,好在 Pinboard 彌補了不足:

實戰Pinba

Pinboard

說到這,估計大家都迫不及待的想試試 Pinba + Pinboard 了,不過從我的經曆來看,想把這套系統跑起來的話需要繞開很多坑,我前前後後搞了五六次才算成功,失敗的主要原因在于各個軟體更新頻率不一樣,依賴關系複雜,于是就出現所有軟體都裝了最新穩定版,但是整個系統卻不能正常運轉,實際上想清楚了也簡單,截止本文發稿前,這些軟體的最新版 Pinboard 最老,是以就以它為參照點,找其它軟體在對應的釋出版本:

  • Pinba 1.1.0:2015-02-12
  • Pinboard 1.5.2:2015-06-09

在安裝 Pinba 之前,先要安裝好 MySQL,在 Pinba 官網描述支援 MySQL 5.1 以上版本,但是我測試了最新穩定版并不能正常工作,穩妥起見,我選擇安裝 MySQL 5.1.72,此版本比較舊,和目前主流版本的安裝步驟略有不同,是以我還是把操作貼出來:

shell> groupadd mysql
shell> useradd -r -g mysql -s /bin/false mysql
shell> tar zxvf mysql-5.1.72.tar.gz
shell> cd mysql-5.1.72
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> cd /usr/local/mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> bin/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql var
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cp support-files/mysql.server /etc/init.d/mysql.server
shell> chmod +x /etc/init.d/mysql.server
shell> chkconfig mysql.server on
shell> /etc/init.d/mysql.server start           

複制

然後安裝 Pinba 1.1.0,記得之前需要先裝好 Judy 1.0.5 和 Libevent 1.4.15:

shell> tar zxvf pinba_engine-1.1.0.tar.gz
shell> ./configure
       --with-judy=/usr/local \
       --with-event=/usr/local \
       --with-mysql=/path/to/mysql/source/code \
       --libdir=/usr/local/mysql/lib/mysql/plugin
shell> make
shell> make install           

複制

接下來在 MySQL 裡加載 Pinba 插件,并建立必要的資料結構:

mysql> INSTALL PLUGIN pinba SONAME 'libpinba_engine.so';
mysql> CREATE DATABASE pinba;
shell> mysql -D pinba < default_tables.sql           

複制

為了稍後在 Pinboard 中使用,我們還需要建立一個賬号來通路 pinba 資料庫:

mysql> GRANT ALL PRIVILEGES ON pinba.* TO pinba@"<HOST>"
       IDENTIFIED BY "<PASSWORD>";           

複制

說明:Pinba 請求池預設儲存 900 秒的資料,也就是 15 分鐘,後續 Pinboard 的 cron 設定必須與此相同,但是不得不說跨度有點長,建議在 my.cnf 裡改為 60 秒:

mysql> SHOW VARIABLES LIKE 'pinba%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| pinba_address                |         |
| pinba_cpu_start              | 0       |
| pinba_data_pool_size         | 0       |
| pinba_histogram_max_time     | 10      |
| pinba_port                   | 30002   |
| pinba_request_pool_size      | 1000000 |
| pinba_stats_gathering_period | 10000   |
| pinba_stats_history          | 60      |
| pinba_temp_pool_size         | 10000   |
| pinba_temp_pool_size_limit   | 1000    |
| pinba_timer_pool_size        | 100000  |
+------------------------------+---------+           

複制

如此 Pinba 就安裝好了,下面需要安裝 PHP 擴充,需要注意的是目前預設倉庫裡儲存的是 PHP7 相關的代碼,如果你和我一樣還使用 PHP5,那麼需要切換分支:

shell> git clone https://github.com/tony2001/pinba_extension.git
shell> cd pinba_extension
shell> git checkout -b php5 remotes/origin/php5
shell> phpize
shell> ./configure
shell> make
shell> make install           

複制

稍後安裝 Pinboard 的時候,還需要安裝 apc 擴充,不過 apc 擴充已經不在維護了,好在我們可以安裝 apcu 擴充,并激活相容模式,用來來實作 apc 擴充的功能:

shell> wget http://pecl.php.net/get/apcu-4.0.11.tgz
shell> tar zxvf apcu-4.0.11.tgz
shell> cd apcu-4.0.11
shell> phpize
shell> ./configure --enable-apc-bc
shell> make
shell> make install           

複制

最後安裝 Pinboard,記得之前需要先安裝好 Composer:

shell> tar zxvf v1.5.2.tar.gz
shell> cd pinboard-1.5.2
shell> composer install
shell> ./console migrations:migrate
shell> ./console register-crontab           

複制

說明:Pinboard 在通過 cron 執行 aggregate 的時候,内部通過一個 lock 檔案來避免并發操作,實際上效果并不好,如果某次執行失敗沒能正常删除鎖檔案,後續操作就無法執行了,其實在設定 cron 的時候搭配作業系統本身的 flock -xn -c … 指令更好。

當然了,我們還需要修改一下 PHP 程式的前端控制器,在裡面激活 Pinba,比如:

<?php

if (extension_loaded('pinba')) {
    ini_set('pinba.enabled', true);
    ini_set('pinba.server', '<IP>');

    pinba_script_name_set($_SERVER['REQUEST_URI']);
}

?>           

複制

一切就緒後,我們可以利用 tcpdump 在伺服器上确認看看有沒有資料:

shell> tcpdump -nn -i any udp port 30002           

複制

本文介紹的都是 Pinba 最基本,同時也是最常用的功能,實際上 Pinba 還有很多殺手級功能,比如 timer,利用它我們可以精确控制監控粒度,實作類似鷹眼的效果,網上能找到很多例子,本文篇幅所限,在這裡我就不再贅述了。

此外,大家可能會關注 Pinba 伺服器的性能如何,如果在大流量網站上使用會不會出現問題,我是在一個日通路量幾百萬左右的網站上部署測試的 Pinba,得益于 Pinba 自定義引擎的性能,MySQL 本身毫無壓力,可以預想千萬級請求量問題不大。如果流量多到幾個億,可能會有問題,但即使那樣也不要緊,我們隻要控制一個采樣百分比就好了。

上一篇: 再叙TIME_WAIT
下一篇: 關于FIN_WAIT2