读《高性能PHP应用开发》笔记

《高性能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