fpm_unix_init_child() setrlimit(RLIMIT_NOFILE) failed: Invalid argument

错误信息:
[ERROR] fpm_unix_init_child(), line 168: setrlimit(RLIMIT_NOFILE) failed: Invalid argument (22)  

根据错误信息可以判定,原因在于rlimit_nofile参数那里。首先要看一下系统中ulimit -n
我做了以下三步:
1.  vim /etc/init.d/nginx  在 start 部分添加
ulimit -SHn 51200 如:
start() {
        echo -n $"Starting $prog: "
        ulimit -SHn 51200
        daemon $NGINX_SBIN -c $NGINX_CONF
        RETVAL=$?
        echo
        return $RETVAL
}

2. vim /usr/local/php/sbin/php-fpm  也在start 部分添加
ulimit -SHn 51200 如:
start)
                echo -n "Starting php_fpm "
                ulimit -SHn 51200
                $php_fpm_BIN --fpm $php_opts

                if [ "$?" != 0 ] ; then
                        echo " failed"
                        exit 1
                fi

3. vim /usr/local/php/etc/php-fpm.conf
修改 rlimit_files 参数为 51200
<value name="rlimit_files">51200</value>

分别重启 nginx 和 php-fpm

说明:其实只要保持nginx,php-fpm启动时 ulimit 数值一致就0k了。

编译php时可能出现的错误以及解决办法

./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache2/bin/apxs --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir  --with-bz2 --with-openssl --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-sockets --enable-exif --disable-ipv6

错误1: configure:error:xml2-config ont found. Please check your libxml2 installation.
解决: yum install -y  libxml2-devel

错误2: configure:error: Cannot find OpenSSL's <evp.h>
解决: yum install -y openssl-devel

错误3: configure: error: mcrypt.h not found. Please reinstall libmcrypt.
解决: yum install -y  libmcrypt-devel

错误4: 在编译php-5.2.10 with php-5.2.10-fpm时,有这样的错误:
/usr/local/src/php-5.2.10/ext/ftp/ ftp.c:291: undefined reference to `SSL_set_fd'
/usr/local/src/php-5.2.10/ext/ftp/ ftp.c:293: undefined reference to `SSL_connect'
/usr/local/src/php-5.2.10/ext/ftp/ ftp.c:287: undefined reference to `SSL_CTX_free'
/usr/local/src/php-5.2.10/ext/ftp/ ftp.c:295: undefined reference to `SSL_shutdown'
collect2: ld returned 1 exit status
make: *** [sapi/cgi/php-cgi] Error 1
解决办法:
1. yum  install -y openssl  openssl-devel  libevent  libevent-devel
2.  make  clean  然后重新  ./config  --with-prefix=/usr/local/php ... (你以前的选项)然后在最后面加上  --with-libevent
3. make

php-fpm.conf两个至关重要的参数

这里规定了PHP-CGI的连接、发送和读取的时间,300秒足够用了,因此我的服务器很少出现504 Gateway Time-out这个错误。最关键的是php-fpm.conf的设置,这个会直接导致502 Bad Gateway和504 Gateway Time-out。
下面我们来仔细分析一下php-fpm.conf几个重要的参数:
php-fpm.conf有两个至关重要的参数,一个是”max_children”,另一个是”request_terminate_timeout”
我的两个设置的值一个是”40″,一个是”900″,但是这个值不是通用的,而是需要自己计算的。
计算的方式如下:
如果你的服务器性能足够好,且宽带资源足够充足,PHP脚本没有系循环或BUG的话你可以直接将”request_terminate_timeout”设置成0s。0s的含义是让PHP-CGI一直执行下去而没有时间限制。而如果你做不到这一点,也就是说你的PHP-CGI可能出现某个BUG,或者你的宽带不够充足或者其他的原因导致你的PHP-CGI能够假死那么就建议你给”request_terminate_timeout”赋一个值,这个值可以根据你服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟-30分钟都可以。由于我的服务器PHP脚本需要长时间运行,有的可能会超过10分钟因此我设置了900秒,这样不会导致PHP-CGI死掉而出现502 Bad gateway这个错误。

而”max_children”这个值又是怎么计算出来的呢?这个值原则上是越大越好,php-cgi的进程多了就会处理的很快,排队的请求就会很少。设置”max_children”也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左右,因此我的”max_children”我设置成40个,20M*40=800M也就是说在峰值的时候所有PHP-CGI所耗内存在800M以内,低于我的有效内存1Gb。而如果我的”max_children”设置的较小,比如5-10个,那么php-cgi就会“很累”,处理速度也很慢,等待的时间也较长。如果长时间没有得到处理的请求就会出现504 Gateway Time-out这个错误,而正在处理的很累的那几个php-cgi如果遇到了问题就会出现502 Bad gateway这个错误。

PHP(以php-cgi-fpm方式启动)的编译安装

需要下载的源码包:php-5.2.8.tar.bz2 和 php-5.2.8-fpm-0.5.7.diff.gz // 版本可以自由选择,但一定要有fpm的那个包
# bzip2 -cd php-5.2.8.tar.bz2 | tar xf -
# gzip -cd php-5.2.8-fpm-0.5.7.diff.gz | patch -d php-5.2.8 -p1
# cd php-5.2.8
# ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysql-sock=/tmp --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt=/usr/local/libmcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --enable-zend-multibyte --disable-ipv6 --enable-fastcgi --enable-fpm
# make
# make install
# mkdir /usr/local/php/etc
# cp php.ini-dist /usr/local/php/etc/php.ini  // 拷贝php的配置文件
# vim /usr/local/php/etc/php-fpm.conf

<value name="listen_address">/tmp/php-fcgi.sock</value> 这一行要改成这样,这里这样修改了以后,在配置nginx的时候就需要注意这个路径了。
修改用户和组的名称为”www”
去掉注释
Unix user of processes
                        <value name="user">www</value>
                        Unix group of processes
                        <value name="group">www</value>
#/usr/local/php/sbin/php-fpm start

Zend 3.3.9的安装

以前老版本 Zend Optimizer 的安装方法是运行安装脚本 ./install.sh,新的Zend Optimizer 3.3.9没有安装脚本,只能按照以下方法安装。

1. 下载文件源文件:  
tar -zxvf ZendOptimizer-3.3.9-linux-glibc23-i386.tar.gz

3. cd ZendOptimizer-3.3.9-linux-glibc23-i386

这里要注意,进入data文件夹后,so 文件是对应版本的,看好系统中的PHP版本再安装。

4. 把 ZendOptimizer.so 文件拷贝到 /usr/local/Zend/lib
cp ZendOptimizer.so /usr/local/Zend/lib

5. 把下列两行加入php.ini,不要加入任何空格和制表符

zend_optimizer.optimization_level=15
zend_extension=/usr/local/Zend/lib/ZendOptimizer.so

# /usr/local/php/bin/php -v
Failed loading /var/soft/bin/apache/modules/ZendOptimizer.so:  ...

也就是说,导致加载ZendOptimizer失败的原因,是因为编译安装Apache2的时候,指定了worker模式 --with-mpm=worker ,Apache2运行在线程模式下。而ZendOptimizer只支持进程模式。也就是Apache2的prefork模式 --with-mpm=prefork 。

于是查看当前的Apache2是否支持了worker模式:
# httpd -l
Compiled in modules:
core.c
worker.c
http_core.c
mod_so.c

是支持worker模式。
解决办法

其实解决的办法很简单,只要重新编译apche,就可以了:
http://mylinux.5d6d.com/thread-20-1-1.html

memcache和memcached在php中的应用

memcache在php中编译
#  wget http://mylinux.5d6d.com/userdirs/c/f/mylinux/memcache-2.2.3.tgz
# tar zxvf memcache-2.2.3.tgz
# cd memcache-2.2.3
# /usr/local/php/bin/phpize
# ./configure --with-php-config=/usr/local/php/bin/php-config
# make
# make install
# cp modules/memcache.so /usr/local/php/ext/
然后在php.ini 中添加
extension = memcache.so
修改扩展路径为:extension_dir = "/usr/local/php/ext"
保存后可以利用 /usr/local/php/bin/php-cgi -m  检测和查看具体的参数


memcached 的编译安装
wget http://memcached.googlecode.com/files/memcached-1.2.8.tar.gz

tar zxvf memcached-1.2.8.tar.gz
cd  memcached-1.2.8
./configure --prefix=/usr/local/memcached
make && make install

启动:

/usr/local/memcached/bin/memcached -m 2048 -p 11211 -l 127.0.0.1 -d -u www
-m  后边指定memecached使用多少内存,单位是M
-p  指定memcached 启动端口
-l  指定绑定的IP
-u  指定以某个账户的身份启动

php-fpm 的slow.log

本帖隐藏的内容需要积分高于 10 才可浏览

[WARNING] fpm_children_bury() php-fpm问题解决方法

centos 5.3 nginx-0.8.31-1.el5 php-fpm-5.2.11
# service php-fpm start
Jan 08 10:55:22.912284 [NOTICE] fpm_unix_init_main(), line 284: getrlimit(nofile): max:1024, cur:1024
Jan 08 10:55:22.913126 [NOTICE] fpm_event_init_main(), line 88: libevent: using epoll
Jan 08 10:55:22.913404 [NOTICE] fpm_init(), line 50: fpm is running, pid 2730
Jan 08 10:55:22.918493 [NOTICE] fpm_children_make(), line 352: child 2731 (pool default) started
Jan 08 10:55:22.922118 [NOTICE] fpm_children_make(), line 352: child 2732 (pool default) started
Jan 08 10:55:22.924813 [NOTICE] fpm_children_make(), line 352: child 2734 (pool default) started
Jan 08 10:55:22.927509 [NOTICE] fpm_children_make(), line 352: child 2735 (pool default) started
Jan 08 10:55:22.929378 [NOTICE] fpm_children_make(), line 352: child 2736 (pool default) started
Jan 08 10:55:22.930268 [NOTICE] fpm_event_loop(), line 107: libevent: entering main loop

# service php-fpm stop
php-fpm.log 会出现以下问题
Jan 08 10:56:22.516549 [NOTICE] fpm_got_signal(), line 56: received SIGTERM
Jan 08 10:56:22.516620 [NOTICE] fpm_pctl(), line 256: switching to ‘terminating’ state
Jan 08 10:56:22.516666 [NOTICE] fpm_pctl_kill_all(), line 172: sending signal 15 SIGTERM to child 2736 (pool default)
Jan 08 10:56:22.516707 [NOTICE] fpm_pctl_kill_all(), line 172: sending signal 15 SIGTERM to child 2735 (pool default)
Jan 08 10:56:22.516729 [NOTICE] fpm_pctl_kill_all(), line 172: sending signal 15 SIGTERM to child 2734 (pool default)
Jan 08 10:56:22.516747 [NOTICE] fpm_pctl_kill_all(), line 172: sending signal 15 SIGTERM to child 2732 (pool default)
Jan 08 10:56:22.516765 [NOTICE] fpm_pctl_kill_all(), line 172: sending signal 15 SIGTERM to child 2731 (pool default)
Jan 08 10:56:22.516778 [NOTICE] fpm_pctl_kill_all(), line 181: 5 children are still alive
Jan 08 10:56:22.517532 [NOTICE] fpm_got_signal(), line 48: received SIGCHLD
Jan 08 10:56:22.517620 [WARNING] fpm_children_bury(), line 215: child 2736 (pool default) exited on signal 15 SIGTERM after 59.588363 seconds from start
Jan 08 10:56:22.518131 [NOTICE] fpm_got_signal(), line 48: received SIGCHLD
Jan 08 10:56:22.518195 [WARNING] fpm_children_bury(), line 215: child 2735 (pool default) exited on signal 15 SIGTERM after 59.590726 seconds from start
Jan 08 10:56:22.518906 [NOTICE] fpm_got_signal(), line 48: received SIGCHLD
Jan 08 10:56:22.518969 [WARNING] fpm_children_bury(), line 215: child 2734 (pool default) exited on signal 15 SIGTERM after 59.594192 seconds from start
Jan 08 10:56:22.519518 [NOTICE] fpm_got_signal(), line 48: received SIGCHLD
Jan 08 10:56:22.519580 [WARNING] fpm_children_bury(), line 215: child 2732 (pool default) exited on signal 15 SIGTERM after 59.597517 seconds from start
Jan 08 10:56:22.520107 [NOTICE] fpm_got_signal(), line 48: received SIGCHLD
Jan 08 10:56:22.520159 [WARNING] fpm_children_bury(), line 215: child 2731 (pool default) exited on signal 15 SIGTERM after 59.601726 seconds from start
Jan 08 10:56:22.520193 [NOTICE] fpm_pctl_exit(), line 81: exiting, bye-bye!

# vi /etc/sysctl.conf
底部添加
fs.file-max=65535
#vi /etc/security/limits.conf
加上
* soft nofile 65535
* hard nofile 65535

make: *** [sapi/cli/php] Error 1 解决办法

ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':
/home/king/php-5.2.13/ext/iconv/iconv.c:2491: undefined reference to `libiconv_open'
collect2: ld returned 1 exit status
make: *** [sapi/cli/php] Error 1
[root@test php-5.2.13]# vim Makefile

在安裝 PHP 到系统中时要是发生「undefined reference to libiconv_open'」之类的错误信息,那表示在「./configure 」沒抓好一些环境变数值。错误发生点在建立「-o sapi/cli/php」是出错,没給到要 link 的 iconv 函式库参数。 解决方法:编辑Makefile 大约77 行左右的地方: EXTRA_LIBS = ..... -lcrypt 在最后加上 -liconv,例如: EXTRA_LIBS = ..... -lcrypt -liconv 然后重新再次 make 即可。

或者用另一种办法

make ZEND_EXTRA_LIBS='-liconv'

ln -s /usr/local/lib/libiconv.so.2 /usr/lib64/

Zend-v3.3.9 下载

3.3.9-i386
http://downloads.zend.com/optimi ... glibc23-i386.tar.gz


v3.3.9-X86
http://downloads.zend.com/optimi ... ibc23-x86_64.tar.gz

让你的php打开fsockopen函数

1.  vi  php.ini
找到 allow_url_fopen 这个参数设置成 On,即
allow_url_fopen = On

2. 让你的php支持 opensll扩展。
默认,是没有openssl扩展的,只能重新编译安装。
yum  install openssl  openssl-devel
cd  /usr/local/src/php-5.2.14/ext/openssl
/usr/local/php/bin/phpize
./configure --with-openssl --with-php-config=/usr/local/bin/php-config
make && make install
看提示,把编译成的openssl.so 拷贝到你在php.ini 中指定的 extension_dir 下

3. vi  php.ini
加入
extension=openssl.so

4. 重启web server

memcached 内存溢出

近几天,发现一个问题。网站的应用中,出现的这样的情况:
一个帖子,第一次打开正常,但刷新几次后就找不到主题,只看到回复。偶尔还会出现,“未定义操作”的错误。经检测,发现是memcached的问题,我们怀疑是memcached刷新缓存过于频繁造成。几台服务器比较,唯有php版本与memcached版本不一样。

正常服务器 php 5.2.8  memcached 1.2.4
不正常服务器 php 5.2.11 memcached 1.2.8

首先我升级了memcached版本,升级成  1.4.0 ,可结果问题依旧。所以只好降低php版本,降低为 5.2.8 ,但memcached版本还是1.4.0. 问题此时解决。

得出结论:php-5.2.11 对memcached 支持不好。不知道更高版本的php是否会解决该问题。

php-5.2.14 下载

http://cn.php.net/distributions/php-5.2.14.tar.bz2   官方站点下载

http://mylinux.5d6d.com/userdirs/c/f/mylinux/attachments/month_1102/php-5.2.14.tar.bz2  本站下载

php.ini 中的mbstring设置编码问题

今天开发的同事,遇到问题。输入中文,总是显示不出来。
他的程序编码定义为了gbk。于是想到了php.ini 的配置,打开php.ini 看到:
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = On
mbstring.http_input = UTF-8
mbstring.http_output = UTF-8
mbstring.detect_order = UTF-8

于是,把这些全部注释掉,就正常了。至于为什么正常了,暂时没有搞明白。

通过构造Hash冲突实现各种语言的拒绝服务攻击



攻击的原理很简单, 目前很多语言, 使用hash来存储k-v数据, 包括常用的来自用户的POST数据, 攻击者可以通过构造请求头, 并伴随POST大量的特殊的”k”值(根据每个语言的Hash算法不同而定制), 使得语言底层保存POST数据的Hash表因为”冲突”(碰撞)而退化成链表.

这个攻击方法危害很高, 攻击成本也很小. 一个台式机可以轻松搞垮数十台, 上百台服务器.

实例:<?php echo '<pre>';
$size = pow(2, 16); // 16 is just an example, could also be 15 or 17
$startTime = microtime(true);
$array = array();
for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $maxKey; $key += $size) {

    $array[$key] = 0;

}
$endTime = microtime(true);

echo 'Inserting ', $size, ' evil elements took ', $endTime - $startTime, ' seconds', "\n";

$startTime = microtime(true);

$array = array();

for ($key = 0, $maxKey = $size - 1; $key <= $maxKey; ++$key) {

    $array[$key] = 0;

}

$endTime = microtime(true);

echo 'Inserting ', $size, ' good elements took ', $endTime - $startTime, ' seconds', "\n";
大家如果有用5.2的, 如果被此类攻击威胁, 可以打上下面的patch, PHP5.3的, 可以考虑升级到5.3.9, 已经包含了此patch(因为5.3.9目前是RC状态, 所以如果不愿意升级, 也可以参照这个patch自己为5.3写一个):

https://github.com/laruence/laru ... -5.2-max-input-vars

另外, 其他语言java, ruby等, 请各位也预先想好对策, 限制post_size是治标不治本的方法, 不过可以用来做临时解决方案.

参考文章:
http://nikic.github.com/2011/12/ ... ng-a-PHP-array.html
http://www.laruence.com/2011/12/30/2440.html