谁都知道监控系统很重要,但是要自己搭建一套好用的系统却不是一件简单的事情。国内已经有不少厂商提供类似的服务,比如:OneAPM、听云,其原理就是通过在服务器上部署一套探针,把数据汇总上报,但是问题却不像说起来这么简单,我曾经买过国内某个厂商高大上的 APM 服务,谁知道它监控的指标太多了,并且无法自定义,结果导致一上线,系统性能就下降百分之二十,最后无奈只好放弃。
我想要的是一种对系统性能影响尽可能小的监控系统,它不需要监控太多指标,只要有 RPS、CPU、内存、响应时间等几个核心数据即可,而 Pinba 简直就是为此量身打造的:PINBA(PHP Is Not A Bottleneck Anymore)原本是 PHP 专用的,其工作原理大致是:在每个请求处理完成后,PHP 把相关数据通过 UDP 发送给 Pinba 自定义的 MySQL 引擎。因为数据是通过 UDP 传输的,所以对原有系统的性能影响很小。如果非要说说 Pinba 的缺点,那么它没有提供一个官方的 UI 算一个,好在 Pinboard 弥补了不足:
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 本身毫无压力,可以预想千万级请求量问题不大。如果流量多到几个亿,可能会有问题,但即使那样也不要紧,我们只要控制一个采样百分比就好了。