手记

PHP性能checklist

  1. 运行环境


    1. 打开慢日志
      log_slow_queries = /var/log/mysql/mysql-slow.log
      long_query_time = 1

    2. Innodb 设置

      innodb_buffer_pool_size = 1Ginnodb_log_file_size = 256Minnodb_log_buffer_size = 4Minnodb_flush_log_at_trx_commit = 2innodb_thread_concurrency = 8innodb_flush_method = O_DIRECT


    1. Nginx


    2. PHP-FPM


    1. workers进程数等于CPU核数
      worker_processes = [CPU cores];

    2. 设置cpu亲密性,每个worker对于一个cpu
      worker_cpu_affinity 01 10; #双核

    3. 使用 limit_zone阻止恶意访问

      limit_req_zone  $binary_remote_addr  zone=qps1:1m   rate=3r/s;location /delay {    limit_req   zone=qps1  burst=5;}


    4. 静态文件缓存

      location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {    expires 24h;    log_not_found off;}


    1. 打开error_log+slow_log,帮助你监控,迅速定位错误
      slowlog = /var/log/php-fpm.$pool.slow
      request_slowlog_timeout = 1
      php_admin_value[error_log] = /var/log/php-fpm.$pool.error

    2. 使用进程池
      PHP支持使用进程池,比如将网站前端和管理后台分别设置两个进程池:
      [fontend]
      # 前端:并发请求多,限制内存占用,限制单请求执行时长
      max_children=100;memory_limit=16M;request_terminate_timeout=15
      [backend]
      # 后端:并发请求少,占用内存大,不限制执行时间
      max_children=10;memory_limit=128M;request_terminate_timeout=0

    3. 设置合理的进程数
      取决于你的PHP程序是IO密集型还是CPU密集型,可使用htop观察;
      IO密集型:100/%MEM
      * 限制内存 php_admin_value[memory_limit] = 32M
      CPU密集型:100/%CPU
      pm = dynamic
      pm.max_children = ?

    4. 设置PHP最长执行时间
      PHP-FPM一个请求独占一个进程,如果不设置超时时间,慢请求会迅速占满所有fpm进程
      request_terminate_timeout = 15

    1. 使用最新的PHP版本 + 20%
      5.5 > 5.4 > 5.3

    2. 使用更快的OPCache缓存 + 20%
      ZendOpcache > APC

    3. 使用Nginx+PHP-FPM 而不是 Apache+mod_php


    4. PHP的mysql扩展使用Mysqlnd驱动,而不是libmysql
      ./configure –with-mysql=mysqlnd –with-mysqli=mysqlnd –with-pdo-mysql=mysqlnd

    5. MySQL


  2. PHP


    1. 架构设计上,避免单点,可水平扩展
      异步解决不了可扩展性问题,总执行时长还是一样多

    2. 设置请求timeout
      避免一个服务延迟,拖累整个页面请求

    3. 合并请求 curl/sql/redis/memcache
      * PHPIO: 循环执行IO函数,记录代码路径重复次数,例如:
      foreach ($users as $uid) {
      mysql_query(‘SELECT * FROM usr WHERE uid = $uid’)
      }
      =>
      mysql_query(‘SELECT * FROM usr WHERE uid IN (‘.implode(‘,’,$users).’)');

    1. 大加载


    2. 反序列化


    3. 使用简单的数据/对象结构
      例如:避免对大数据集使用Active Record

    1. 使用大数组作为配置文件
      使用hidef 一次性载入

    2. 载入不需要的类/库文件
      lazyload,按需加载库文件

    1. 使用更快的序列化/反序列化方法
      explode > msgpack > igbinary > json> serialize

    2. 避免反序列化大对象(同大加载)
      保持小对象的序列化/反序列化,不要缓存大数据,检测方法同上

    1. 优化原则
      抓大放小(总执行时长=执行时长*执行次数)
      * 安装xhprof+XHGui;进入Hardest Hit ,按Total Wall Time(总执行时长)排序

    2. CPU
      * 监测代码执行前后的,脚本使用内存变化



    3. IOwait



0人推荐
随时随地看视频
慕课网APP