《高性能PHP应用开发》这本书最值得学习的其实是一个思路:
要诊断问题,从目标的全生命周期出发,用合适的工具去测试和衡量,逐环节排查优化。
HTTP请求的生命周期
对于用户来说,一个HTTP请求的生命周期如上图,其中有一个环节慢,都会导致卡顿。
DNS/PING响应延迟检测工具:http://ping.chinaz.com/
WEB服务生命周期
服务器压力测试工具:ab
前端
这个环节往往是最容易被PHP程序员忽略的环节,但对用户实际体验提升最大的,往往正是这个环节。
前端性能检测和优化工具:
- chrome自带的
- firebug
- google的Page Speed
- yahoo的Yslow
- YUI compressor(JS和CSS压缩工具)
- Gulp组件(前端静态文件编译,合并,压缩)
常用处理措施:
- 开启Gzip
- 开启Keep-alive
- 设置静态文件浏览器cache周期
- 压缩和合并CSS,JS文件,减少请求数量
- 压缩图片,小图用GIF,大图用JPG,其余用PNG
<script
尽量底部引入
PHP编码最佳实践
这个环节有很多PHP语言层面提升性能的技巧,其实大多数对性能提升是比较有限的。值得一说的是file_get_content()
这个函数,有内存映射,在内存允许的情况下,读写大文件性能更好,不过一定注意内存消耗。读取小文件的时候fread()
函数会更好,内存开销也更小。
在PHP语言层面,我们重点介绍一套,指引我们优化PHP性能的工具。
- VLD(反汇编程序)
- strace(跟踪PHP脚本底层C语言的调用)
- xdebug(PHP脚本性能分析工具)
blackfire(第三方PHP性能分析服务)
VLD
这个东西可以用pecl安装,以PHP拓展形式存在,用命令行的方式调用,很方便。 这个工具,可以看到PHP脚本调用C函数的情况,一般情况下函数调用(number of ops)次数越少,性能越好。
strace
这东西用法就不细说了,提供的信息如下
可以看到也是一些C函数的调用
xdebug
这个太有名,略
blackfire
这个是第三方提供的性能分析服务
opcode缓存
熟悉PHP的朋友都知道,PHP脚本执行,是要先编译成opcode再解释执行的。书里面的内容有点过时了,我们现在可以直接开启opcache,就可以缓存opcode在内存里了,注意根据需求设置检测文件修改的配置。
变量/数据缓存
这个环节也就是我们通常Redis,Memcached的使用,不细说。
Web服务器
预备概念,线程和进程的区别
简单说,apache每支持一个连接都需要开一个线程,都会占用内存,所以apache对于高并发需要更多内存,优点是保证了线程安全,不会有诡异的PHP扩展错误。
nginx是异步架构,一个线程就可以应付很多连接,所以对内存消耗更低,缺点是nginx跑PHP可能不如apache稳定。
对于静态文件分发的Nginx超过Apache十倍以上,对于PHP请求分发,Nginx超过Apache一倍以上。
数据库
数据库的性能优化是一个大话题,我简要说下,
减少数据库连接,少连接就是少线程,少内存。
区分Myiasm和Innodb的特点,选择合适的引擎。
重点配置好mysql,基本思路是把mysql常用结果集全部缓存在内存中,(单线程所需内存*连接数)+全局mysql所需内存 必须小于我们的物理内存的8成,我们知道内存交换去读写磁盘是很慢的。
利用好慢查询和explain语句去查sql语句性能瓶颈在哪。
利用mysqltunner.pl工具优化mysql配置,其实phpmyadmin也有。
写程序一开始就把读写分开为两个链接。
主写,从读。
分布式/负载均衡
dns轮询就不说了,注意dns可以给指定地区解析指定ip实现均衡负载。
负载均衡主流方案是用一台nginx把请求分发给各台PHP服务器。
我们主要看均衡负载的坑:
雪崩效应,我有2台PHP服务器,有1台挂了,另外一台又坑不住全部流量,也挂了。所以设计服务器集群的时候要给整个集群预留足够的处理能力。
共享PHP会话,把所有PHP会话集中到一个memcached或者redis