记一次接口性能测试引发的Linux+Apache+PHP调优过程

一. 概述

项目验收阶段, 需要对部分PHP接口进行性能测试, 性能测试环境架构为如下所示:


image.png

使用ab压力测试, 2000请求, 500并发, 发现性能瓶颈在Apache和PHP之间, 对底层原理不了解, 调优过程曲折迷离, 将其记录下来, 日后再仔细琢磨!

  • PHP版本: 7.0.4
  • Apache版本: 2.4.18
  • MySQL版本: 5.7.11

二. 优化Linux内核参数

vim /etc/sysctl.conf, 在末尾加入如下内容

net.core.somaxconn = 2048
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 20000
net.ipv4.ip_local_port_range = 5000 65000
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216
net.ipv4.tcp_mem = 786432 2097152 3145728
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_max_orphans = 131072
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_syncookies = 1
fs.nr_open = 1000000

执行sysctl -p生效
需要根据自己机器配置做相应的调节

参考博客如下

https://blog.csdn.net/aresiii/article/details/48374987
https://blog.csdn.net/leonpengweicn/article/details/50477530
https://blog.csdn.net/tallercc/article/details/52823075

三. 优化Apache

1. Apache工作模式调优,

  • 查看Apache工作模式
    /usr/local/apache2/bin/apachectl -l
  core.c
  mod_so.c
  http_core.c
  event.c(event模式)
  • 在主配置文件里开启mpm
    vim /usr/local/apache2/conf/httpd.conf
Include conf/extra/httpd-mpm.conf
  • 根据各自的不同的工作修改mpm中对应的配置
    vim /usr/local/apache2/conf/extra/httpd-mpm.conf

参考博客:

https://blog.csdn.net/STFPHP/article/details/52954303
http://blog.jobbole.com/91920/
http://www.cnblogs.com/fazo/p/5588644.html

2. Apache 重写机制调优

将index.php重写规则写到Apache配置文件里, 而不是使用.htaccess文件, 禁用.htacess文件读取, 配置如下

DocumentRoot "/home/uar/uar/codes/web/uar-web/public"
<Directory "/home/uar/uar/codes/web/uar-web/public">
    #Options Indexes FollowSymLinks
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   AllowOverride FileInfo AuthConfig Limit
    # 不查找.htaccess文件
    AllowOverride None
    # 重写需要配置该条
    Options FollowSymLinks
    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>

参考博客:
http://www.jb51.net/article/31721.htm

3. 开启KeepAlive On长连接

Include conf/extra/httpd-default.conf

根据需要调节配置文件

四. PHP调优

本次压测系统使用Laravel5.2编写, PHP版本为7.0.4
强烈推荐看<strong>鸟哥博客</strong>:
http://www.laruence.com/2015/12/04/3086.html
https://blog.csdn.net/qq_36031499/article/details/53911734

1. 开启opcache(性能提高了5倍, 强烈推荐)

在php.ini最后加入如下配置, 开启opcache

zend_extension="opcache.so"
; 开关打开
opcache.enable=1
; ; 设置共享内存大小, 单位为:Mb
opcache.memory_consumption=2048
; ;如果启用,那么 OPcache 会每隔 opcache.revalidate_freq 设定的秒数 检查脚本是否更新。 如果禁用此选项,你必须使用 opcache_reset() 或者 opcache_invalidate() 函数来手动重置 OPcache,也可以 通过重启 Web 服务器来使文件系统更改生效。
opcache.validate_timestamps=1
;opcache.enable_cli=0

;求得uar项目PHP文件为35846, opcache.max_accelerated_files应该比项目文件数大
opcache.max_accelerated_files=50000
opcache.interned_strings_buffer=64
opcache.fast_shutdown=1

参考博客: https://www.abcdocker.com/abcdocker/2151
opcache文档: https://www.scalingphpbook.com/blog/2014/02/14/best-zend-opcache-settings.html

2. Laravel层面的优化

  • 由于是接口性能测试, 去掉没有必要的中间件
  • 关掉debug
  • 将无用的日志打印去掉
  • 生成配置文件缓存
    .....

参考博客: https://segmentfault.com/a/1190000011569012

ab相关博客
https://blog.linuxeye.cn/124.html
https://blog.csdn.net/officercat/article/details/49891809
https://www.cnblogs.com/hedy-x/p/8065802.html

五. MySQL相关调优文档

https://www.cnblogs.com/angryprogrammer/p/6667741.html
https://segmentfault.com/a/1190000011687570
https://segmentfault.com/a/1190000014108616
https://blog.csdn.net/linuxlsq/article/details/52606255

附录: 关于opcache的配置说明

参考博客: https://gywbd.github.io/posts/2016/1/best-config-for-zend-opcache.html

zend opcache的最佳设置

在网上无意中看到的一篇文章,这哥们非常简洁地谈论了zend opcache的最佳设置,他说他为此花了大量的时间探索zend opcache的每个设置选项的细节,甚至是阅读它的源代码,并且在自己的项目中实践(一个每天有117 million的HTTP请求的应用)。个人觉得这种文章相当有指导意义,所以特地把它的设置方式摘译如下(格式有些修改):

opcache.revalidate_freq

这个选项用于设置缓存的过期时间(单位是秒),当这个时间达到后,opcache会检查你的代码是否改变,如果改变了PHP会重新编译它,生成新的opcode,并且更新缓存。值为“0”表示每次请求都会检查你的PHP代码是否更新(这意味着会增加很多次stat系统调用,译注:stat系统调用是读取文件的状态,这里主要是获取最近修改时间,这个系统调用会发生磁盘I/O,所以必然会消耗一些CPU时间,当然系统调用本身也会消耗一些CPU时间)。可以在开发环境中把它设置为0,生产环境下不用管,因为下面会介绍另外一个设置选项。

opcache.validate_timestamps

当这个选项被启用(设置为1),PHP会在opcache.revalidate_freq设置的时间到达后检测文件的时间戳(timestamp)。

如果这个选项被禁用(设置为0),opcache.revalidate_freq会被忽略,PHP文件永远不会被检查。这意味着如果你修改了你的代码,然后你把它更新到服务器上,再在浏览器上请求更新的代码对应的功能,你会看不到更新的效果,你必须得重新加载你的PHP(使用kill -SIGUSR2强制重新加载)。

这个设定是不是有些蛋疼,但是我强烈建议你在生产环境中使用,why?因为当你在更新服务器代码的时候,如果代码较多,更新操作是有些延迟的,在这个延迟的过程中必然出现老代码和新代码混合的情况,这个时候对用户请求的处理必然存在不确定性。

opcache.max_accelerated_files

这个选项用于控制内存中最多可以缓存多少个PHP文件。这个选项必须得设置得足够大,大于你的项目中的所有PHP文件的总和。我的代码库大概有6000个PHP文件,所以我把这个值设置为一个素数7963(译注:不知道这哥们为什么要设置这个数,7963也不是大于6000的最小素数)。

你可以运行“find . -type f -print | grep php | wc -l”这个命令来快速计算你的代码库中的PHP文件数。

opcache.memory_consumption

这个选项的默认值为64MB,我把它设置为192MB,因为我的代码很大。你可以通过调用opcachegetstatus()来获取opcache使用的内存的总量,如果这个值很大,你可以把这个选项设置得更大一些。

opcache.interned_strings_buffer

这是一个很有用的选项,但是似乎完全没有文档说明。PHP使用了一种叫做字符串驻留(string interning)的技术来改善性能。例如,如果你在代码中使用了1000次字符串“foobar”,在PHP内部只会在第一使用这个字符串的时候分配一个不可变的内存区域来存储这个字符串,其他的999次使用都会直接指向这个内存区域。这个选项则会把这个特性提升一个层次——默认情况下这个不可变的内存区域只会存在于单个php-fpm的进程中,如果设置了这个选项,那么它将会在所有的php-fpm进程中共享。在比较大的应用中,这可以非常有效地节约内存,提高应用的性能。

这个选项的值是以兆字节(megabytes)作为单位,如果把它设置为16,则表示16MB,默认是4MB,这是一个比较低的值。

opcache.fast_shutdown

另外一个很有用但也没有文档说明的选项。从字面上理解就是“允许更快速关闭”。它的作用是在单个请求结束时提供一种更快速的机制来调用代码中的析构器,从而加快PHP的响应速度和PHP进程资源的回收速度,这样应用程序可以更快速地响应下一个请求。把它设置为1就可以使用这个机制了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容