Ter um desafio para descobrir por que os resultados são como são. Talvez faltando algo óbvio. Desculpe, isso não é muito específico. Mas se alguém tiver uma indicação sobre áreas para focar isso seria muito útil. Felicidades.
Teste de carga
São cerca de 5486 gravações em db por minuto / 90 por segundo. Eu posso ver os seguintes erros nos logs conforme os servidores ficam sobrecarregados:
- 11: Recurso temporariamente indisponível) ao conectar-se ao upstream
- Tempo limite da produção upstream (110: Tempo limite da conexão esgotado) durante a leitura do cabeçalho de resposta do upstream
Problema
Ao executar o teste de carga, veja os seguintes problemas:
- A página que executa a atualização / gravação (aquela que o teste de carga está atingindo) diminui e demora 10 20 segundos para carregar.
- 404 arbitrários dados pelo Nginx em qualquer uma das páginas. Os resultados mostram que talvez 10-20% das solicitações durante o período de pico resultam em 404.
Acho que eles são dois problemas separados e possivelmente não relacionados. Não consigo ver linhas planas nos gráficos, o que sugere um limite sendo atingido.
- Os servidores Web ficam em torno de 60% da CPU e permanecem estáveis. RAM parece OK.
- Os servidores de banco de dados ficam em torno de 20% da CPU e permanecem estáveis. RAM parece OK.
- Conexões de banco de dados vão para 1500/2000. Isso parece duvidoso. Embora não seja uma linha plana, o que sugere que não está atingindo um limite.
- Os limites de conexão de rede parecem estar OK.
- Tabelas indexadas sempre que possível / apropriado.
Infraestrutura
AWS RDS MySQL
1 x operações de gravação db.m3.xlarge
1 x db.m3.xlarge DB Replicado para operações de leitura
Webservers do AWS EC2 Linux, Nginx, PHP-FPM
6 x c3.2xlarge
Config
/etc/php-fpm.d/domain.com.conf
[domain.com]
user = nginx
group = nginx
;;;The address on which to accept FastCGI requests
listen = /var/run/php-fpm/domain.com.sock
;;;A value of '-1' means unlimited. Althought this may be based on ulimit hard limit.
;;;May be worth setting as desired in case of the above.
listen.backlog = -1
;;;dynamic - the number of child processes is set dynamically based on the following directives: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.
pm = dynamic
;;;maximum number of child processes to be created when pm is set to dynamic
pm.max_children = 512
;;;The number of child processes created on startup. Used only when pm is set to dynamic.
pm.start_servers = 8
;;;The desired minimum number of idle server processes. Used only when pm is set to dynamic.
pm.min_spare_servers = 2
The desired maximum number of idle server processes. Used only when pm is set to dynamic
pm.max_spare_servers = 16
;;;The number of requests each child process should execute before respawning.
pm.max_requests = 500
;;;The URI to view the FPM status page.
pm.status_path = /status/fpm/domain.com
;;;The timeout for serving a single request. This option should be used when the 'max_execution_time' ini option does not stop script execution
request_terminate_timeout = 30
;;;Set open file descriptor rlimit. Default value: system defined value.
;;;rlimit_files
;;;rlimit_core int
;;;Set max core size rlimit. Possible Values: 'unlimited' or an integer greater or equal to 0. Default value: system defined value.
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 8M
php_admin_value[disable_functions] = exec,passthru,system,proc_open,popen,show_source
;;; Site specific custom flags go here
;;; End of site specific flags
slowlog = /var/log/nginx/slow-query-$pool.log
request_slowlog_timeout = 10s
chdir = /
Nginx - /etc/nginx/nginx.conf
events {
worker_connections 19000;
# essential for linux, optmized to serve many clients with each thread
use epoll;
multi_accept on;
}
worker_rlimit_nofile 20000;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format proxy_combined '$http_x_real_ip - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log proxy_combined;
sendfile on;
## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size 1K;
client_header_buffer_size 1k;
# client_max_body_size 1k;
large_client_header_buffers 2 1k;
## END: Size Limits & Buffer Overflows ##
## Start: Caching file descriptors ##
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
## END: Caching
## Start: Timeouts ##
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
## End: Timeouts ##
server_tokens off;
tcp_nodelay on;
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/html text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
client_max_body_size 30M;
proxy_cache_path /var/cache/nginx/c2b levels=1:2 keys_zone=c2b-cache:8m max_size=100m inactive=60m;
proxy_temp_path /var/cache/tmp;
proxy_ignore_headers Set-Cookie X-Accel-Expires Expires Cache-Control;
# allow the server to close the connection after a client stops responding. Frees up socket-associated memory.
reset_timedout_connection on;
include /etc/nginx/conf.d/*.conf;
}
Site específico do NGINX - /etc/nginx/conf.d/domain.com
# pass the PHP scripts to FastCGI server listening on
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/domain.com.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/domain.com/public_html/$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 30;
}