我正在我的 nginx 服务器上运行一些围攻测试。瓶颈似乎不是 CPU 或内存,那么它是什么?
我尝试在我的 MacBook 上执行此操作:
sudo siege -t 10s -c 500 server_ip/test.php
响应时间为 10 秒,在完成之前出现错误并且围攻中止。
但如果在我的服务器上运行上述内容
siege -t 10s -c 500 localhost/test.php
我得到:
Transactions: 6555 hits
Availability: 95.14 %
Elapsed time: 9.51 secs
Data transferred: 117.30 MB
Response time: 0.18 secs
Transaction rate: 689.27 trans/sec
Throughput: 12.33 MB/sec
Concurrency: 127.11
Successful transactions: 6555
Failed transactions: 335
Longest transaction: 1.31
Shortest transaction: 0.00
我还注意到,对于较低的并发数字,与外部相比,本地主机上的交易率得到了极大提高。
但是当上述程序在本地主机上运行时,CPU 使用率较低,HTOP 上的内存使用率也较低。因此,我不知道如何提高性能,因为我看不到瓶颈。
ulimit 返回 50000,因为我已经将其增加了。有 4 个 nginx 工作进程,是我的 CPU 核心的 2 倍。以下是我的其他设置
worker_rlimit_nofile 40000;
events {
worker_connections 20000;
# multi_accept on;
}
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
test.php 只是一个 echo phpinfo() 脚本,没有其他内容。没有数据库连接。
我相信该机器是 AWS m3 大型机器,有 2 个 CPU 核心和大约 7GB 的 RAM。
这是我的服务器块的内容:
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/sitename;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
location / {
try_files $uri $uri.html $uri/ @extensionless-php;
}
location @extensionless-php {
rewrite ^(.*)$ $1.php last;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
我的 php-fpm 设置:
pm = dynamic
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 40
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 30
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 20
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 35
; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
;pm.process_idle_timeout = 10s;
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
;pm.max_requests = 500
答案1
对于这么小的 PHP 进程池来说,500 个并发请求实在太多了。尝试提高最小和最大 php 进程数,然后再次测试,直到达到最大 CPU 使用率。
最肯定的是,如果您使用较低的客户端并发性(可能是 100,因为每个请求的 CPU 使用率较低)执行测试,您将获得更好的全局性能并且不会出现请求错误。同样,如果您执行测试的时间更长,您应该会观察到越来越糟糕的统计数据和更高的错误率。
无论如何,一旦达到 100% CPU 使用率测试场景,请记住,当您部署生产代码时,这些池值将毫无用处。典型的 PHP 电子商务应用程序的 CPU 密集程度足以让您的 2 个 vCPU 因仅 4-5 个并发结账而挨饿。
通常,CPU 或内存密集型应用程序更适合使用小型 PHP 进程池,而快速的低 CPU 应用程序则更适合使用大型池。