一、测试环境
1、测试目标
A、梳理PHP+Apache、PHP+Nginx的基本工作模式和配置方式,给没有经验的PHP应用部署人员做参考
B、以简单、标准的测试方式,对ECS在不同的PHP部署方式下的性能表现做测评,方便用户对比阿里云ECS与物理机、或与其他云服务器做对比
2、ECS配置
杭州集群,2核4G,centOS6.5 64位,磁盘20+100GB,100Mbps公网带宽(有的测试中被升级为200Mbps,会有注明)
3、压测工具
PAP
4、PHP+Apache(mpm模块,又分为event和prefork两种模式)
1) apache2.4.12, php 5.6.6。Apache依赖apr、apr-util和pcre,版本如下:
apr-1.5.1
apr-util-1.5.4
pcre2-10.00。安装过程中pcre2编译头文件问题,修改为pcre-8.36,完成编译安装。
编译指令:
./configure --with-pcre=/usr/local/pcre --enable-so (详细参数配置可以参考网上说明)
缺省加载模块
core_module (static)
so_module (static)
http_module (static)
mpm_event_module (static)
2) 配置修改
完成几个配置文件的修改,主要是httpd.conf,httpd-mpm.conf, php.ini,完成对PHP模块的加载、文件类型map等基础配置。Mpm配置未修改
A、Httpd.conf
LoadModule deflate_module modules/mod_deflate.so,打开压缩
LoadModule php5_module modules/libphp5.so, 开启php5支持
ServerLimit 500,修改XXXXXX
LogLevel info,修改日志级别用以调试
配置对PHP执行的文件类型
AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php-source .phps
压缩配置
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml text/javascript
指定mpm配置文件
Include conf/extra/httpd-mpm.conf
…..
B、httpd-mpm.conf
配置这个文件前,必需先搞清楚apache当前采用的是哪种工作模式,在本次测试中分别使用了event模式和prefork模式(关于几种工作模式的区别、以及对比,网上很详细,这里不再累述)。Apache2.4.12缺省在centOS下是采用event模式,典型配置如下:(详细的参数说明请参考配置文件内的说明及网上资料)
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
切换模式时需要重新编译apache,显式指定:
./configure --with-pcre=/usr/local/pcre --enable-so --with-mpm=prefork
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 400(缺省是250,但是为了和event方式做对比,故修改为和worker数量限制一致)
MaxConnectionsPerChild 0
</IfModule>
同时,关于Apache MPM的Serverlimit和ThreadLimit的功能设定,有一篇文章写得比较清楚,参考如下链接:
http://blog.sina.com.cn/s/blog_564fc50a0100nwcq.html
C、php.ini
因为此次测试中未连接数据库等,所以没有修改Php.ini的缺省配置。
从环境角度,需要重点关注“Resource Limits”部分,例如:
max_execution_time = 30
memory_limit = 128M
………
在实际应用当中,php.ini是非常关键的,需要专题研究。
5、PHP+Nginx
1) 重新编译php566,支持fpm,需要make uninstall、distclean,将原有编译配置等全部清除, php-fpm功能就不能编译支持apache的apxs模块功能,不然报错
编译开关 ./configure –enable-so –enable-fpm
2) 配置fpm
编译完成,修改fpm设置/usr/local/etc/php-fpm.conf
pid = run/php-fpm.pid
error_log = log/php-fpm.log
log_level = notice
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 400
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp/php
env[TMPDIR] = /tmp/php
env[TEMP] = /tmp/php
配置完成,启动fpm ,检查端口正常
3) 编译安装nginx,需要熟悉nginx的日常管理命令
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre=/tmp/pcre-8.36 --http-client-body-temp-path=/tmp/nginx_client --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --http-uwsgi-temp-path=/tmp/nginx/uwsgi --http-scgi-temp-path=/tmp/nginx/scgi
4) 配置nginx
Nginx配置,主要是如下项:
worker_processes 2; ##根据服务器规格配置进程数
error_log logs/error.log; ##配置日志文件
##压缩配置
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
##最重要的,fastcgi的配置
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
include fastcgi.conf;
}
fastcgi.conf采用缺省配置没有修改
##测试中根据错误提示修改
worker_connections 65535; ##缺省值为1024
二、场景说明
为了排除应用差异和数据库操作差异可能带来的复杂性、仅仅评测与应用无关的简单场景(易于与物理机环境、或其他云服务商进行对比),在每一种测试环境下,都会测试3个典型场景,分别说明如下:
1、 PHPInfo
PHP服务端调用phpinfo(INFO_GENERAL),php文件如下:
<html>
<head>
<title>PHP Tes</title>
</head>
<body>
<?php phpinfo(INFO_GENERAL); ?>
</body>
</html>
目标:标准的php配置测试方法,有少量运算量,同时需要有一定的带宽要求
2、 For
PHP服务端调用一个纯粹的for循环,php文件如下:
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
for ($i = 1; $i <=1000000; $i++){
$j = $i +1;
}
?>
</body>
</html>
目标:纯粹的for循环简单计算,无休眠时间,耗CPU,有很小的带宽需求
3、 Forsleep
Php端调用for循环,但是只执行sleep操作:
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php
for ($i = 1; $i <=1; $i++){
usleep(50000);
}
?>
</body>
</html>
目标:服务处理几乎不耗用CPU,仅考验各种配置下多进程、线程调度能力,也不占用带宽
三、测试过程(内容太多,参考附件)
1、 Apache+mpm_event+PHPinfo
2、 Apache+mpm_event+For
3、 Apache+mpm_event+Forsleep
4、 Apache+mpm_prefork+PHPInfo
5、 Apache+mpm_prefork+For
6、 Apache+mpm_prefork+Forsleep
7、 Nginx+PHPinfo
8、 Nginx+For
9、 Nginx+Forsleep
四、测试总结
首先,对三种测试场景下、不同环境的TPS及平均时延(正常压力下,未超负荷运行)做一个对比
其他的对比项:
1、 仅就这个简单的测试场景,三种部署方式并无显著的性能差异,各种服务器在细节性能调优方面的特性都没有展现出来,也不是本文的目的:) Nginx在响应时间方面的优势,据说也是可以通过apache配置解决的:
http://www.eschrade.com/page/why-is-fastcgi-w-nginx-so-much-faster-than-apache-w-mod_php/
感兴趣的话可以试一下
2、 Apache的mpm_prefork模式,因为采用单进程单线程方式,配置和异常隔离都比较好,在测试中压力过大时,仅出现很正常的警告和错误信息,但是进程的创建和销毁显然比mpm_event要慢,在突发尖峰时进程创建速度明显比线程慢(不过也不是大问题,也在可接受范围内,而且可以采用预配置的方式减少动态过程);mpm_event方式在网络带宽不够时,出现过进程退出以及defunct的情况,具体原因没有再查(另外,event是worker模式的升级,worker不是线程安全的,event还没有查到明确说明、估计也不是,所以在应用时一些模块不一定支持线程安全模式),但是至少说明event方式的配置和维护其实更需要经验;nginx的配置也很简单,测试中也未产生意外的问题,但是fpm进程数量的配置要比较小心,因为配置过高会直接导致系统内存耗光、导致OS重启。
3、 各种方式下对于worker的总数(包括event下的进程*线程、prefork下的进程、nginx下的进程*client)设定为400,在For测试(最耗CPU)测试并发200线程时出现响应时间急剧恶化,700线程(无思考时间)时,都开始出现请求失败的情况。
4、 关于Apache和nginx支持PHP的对比,网上有很多,摘了个感觉比较好的:
http://www.banghui.org/2972.html
总之,因为nginx的前端缓存、事件驱动方式(apache的event方式也做了改进,但是目前显然还不是很成熟),高并发处理能力较好、天生的反向代理;但apache发展更久,后端处理功能更加强大。所以很多人用nginx前端处理静态请求+apache后端处理动态内容。
通过For测试也可以看出,对于这种动态的请求及调度,虽然nginx前端承受并发的能力很好,但是端口转发及调度、造成Ngnix+fpm的表现不如apache(也许配置还可以优化、但至少对于入门者配置维护比较麻烦);
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。