php, nginx高并发优化

linux内核层面

以centos7.0为例

# 允许等待中的监听
 
echo 50000 >/proc/sys/net/core/somaxconn  
 
#tcp连接快速回收
echo 1 >/proc/sys/net/ipv4/tcp_tw_recycle  
 
# tcp连接重用 
echo 1 >/proc/sys/net/ipv4/tcp_tw_reuse   
 
#不抵御洪水攻击
echo 0 >/proc/sys/net/ipv4/tcp_syncookies   

nginx优化

worker_process

worker_process 修改为内核数的1-2倍, 一般是4或8, 8以上优化不大

这里需要注意, 开太多的worker进程, 会增加cpu开销,cpu占用会增高

keepalive_timeout

高并发下设为0

但是文件上传需要保持连接, 开发时需注意, 做好业务拆分

worker_connections

设置worker进程最大打开的连接数, 建议尽量高,比如20480

worker_rlimit_nofile

将此值增加到大于worker_processes * worker_connections的值。 应该是增加当前worker运行用户的最大文件打开数值

php-fpm

2020年5月4日22:09:18

php-fpm 可以选择sock 和 tcp连接方式, 高并发下可以使用sock连接, 经过实测可以提高 20% 左右的rps(35 -> 42) , 不过技术稳定性较差

emergency_restart*

# 60秒内有10次子进程中断,则重启php-fpm, 防止因php垃圾代码造成的中断问题
emergency_restart_threshold =10
emergency_restart_interval =60

process.max

允许的最大进程数, 一个php-fpm进程大约占用15-40m的内从, 具体设置值需要根据实际情况得出 我这里设为 512

pm.max_children

某个连接池允许的最大子进程, 不要超过process_max

pm.max_requests

允许的最大请求 ,设置2048

关掉慢请求日志

;request_slowlog_timeout = 0
;slowlog = var/log/slow.log

成果

环境

硬件

  • i5-3470 CPU
  • 4g 内存

软件

  • php7.1.30
  • thinkPHP 5.1.35
  • nginx

业务说明

ab 到 thinkPHP框架首页面, tp开启了强路由模式, 未配置首页路由, 走到miss 路由, 返回miss信息, 未调用db,返回的miss信息如下:

{"code":-8,"msg":"api不存在"}

ab测试结果, 1w并发, 请求10次, 共10w请求

D:\soft\phpstudy\PHPTutorial\Apache\bin>ab -c 10000 -n 100000 http://fs_server.test/
This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking fs_server.test (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests


Server Software:        nginx
Server Hostname:        fs_server.test
Server Port:            80

Document Path:          /
Document Length:        32 bytes

Concurrency Level:      10000
Time taken for tests:   492.928 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      19500000 bytes
HTML transferred:       3200000 bytes
Requests per second:    202.87 [#/sec] (mean)
Time per request:       49292.784 [ms] (mean)
Time per request:       4.929 [ms] (mean, across all concurrent requests)
Transfer rate:          38.63 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    2   6.6      2    1365
Processing: 18749 46094 8055.0  49145   52397
Waiting:    12231 45636 8504.8  48793   51627
Total:      18751 46096 8055.0  49147   52399

Percentage of the requests served within a certain time (ms)
  50%  49147
  66%  49279
  75%  49347
  80%  49386
  90%  49473
  95%  49572
  98%  49717
  99%  50313
 100%  52399 (longest request)

无丢失的请求, 就是花费时间有些长, 毕竟虽然没走db,也是走的一套完整的tp框架, 总体算是合理的结果

不过这块有个非常难堪的问题, 如果进行mysql,redis的操作, 会因为存储媒介的连接问题, 造成响应丢失, nginx直接5XX错误,初步方案是提高其最大连接数待测试.

附几个常用指令, 可以查看当前开启了几个fpm进程, 总内存开销, 正在处理请求的进程等

# 确认php-fpm的worker进程是否够用,如果不够用就等于没有开启一样 
计算开启worker进程数目:
ps -ef | grep 'php-fpm'|grep -v 'master'|grep -v 'grep' |wc -l

#计算正在使用的worker进程,正在处理的请求
netstat -anp | grep 'php-fpm'|grep -v 'LISTENING'|grep -v 'php-fpm.conf'|wc -l

# 内存开销
ps auxf | grep php | grep -v grep | grep -v master | awk '{sum+=$6} END {print sum}'
posted @ 2019-06-05 10:56  also_think  阅读(1995)  评论(0编辑  收藏  举报