nginx bloquea algunas solicitudes POST por un tiempo

nginx bloquea algunas solicitudes POST por un tiempo

Tengo la siguiente pila ejecutándose en Ubuntu 18.08 y definida como docker-compose:

  1. en vez demariadb:10.3.20
  2. instancia de wordpress personalizada basada en wordpress:5.3.0-php7.2lo instalado ioncubeen ella
  3. instancia de nginx personalizada basada en nginx:1.13lo instalado nginx-amplify-agenten ella

configuración de nginx:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  10000;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';

    log_format  main_ext  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for" '
                          '"$host" sn="$server_name" '
                          'rt=$request_time '
                          'ua="$upstream_addr" us="$upstream_status" '
                          'ut="$upstream_response_time" ul="$upstream_response_length" '
                          'cs=$upstream_cache_status' ;

    access_log  /var/log/nginx/access.log  main_ext;
    error_log  /var/log/nginx/error.log warn;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

El sitio se define de la siguiente manera:

server {
        listen 80;
        listen [::]:80;

        server_name some.org www.some.org;

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name some.org www.some.org;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/some.org/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/some.org/privkey.pem;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                proxy_connect_timeout 600;
                proxy_send_timeout    600;
                proxy_read_timeout    600;
                proxy_redirect        off;
                proxy_pass http://wordpress;

                proxy_set_header      X-Real-IP $remote_addr;
                proxy_set_header      X-Forwarded-Proto https;
                proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header      Host $host;
        }

        location = /favicon.ico {
                log_not_found off; access_log off;
        }

        location = /robots.txt {
                log_not_found off; access_log off; allow all;
        }

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

Toda la pila funciona como se esperaba, a menos que entre 10 y 15 usuarios accedan al sitio web e intenten realizar acciones. En este caso, algunas solicitudes comienzan a bloquearse (generalmente es la misma solicitud POST para algún componente) y después de 3 a 4 minutos se está procesando. lanzado sin ningún error y el usuario puede ver el resultado. Durante el bloqueo, el sitio no se hace responsable del mismo navegador (¡pero de otros todo está bien!). Una vez liberada la solicitud, el sitio vuelve a ser responsable.

Los registros también son bastante extraños:

  • Una vez que la solicitud colgada/pendiente llega al servidor, se muestra en los registros de acceso de nginx pero no en los registros de wordpress.
  • Una vez que la solicitud finalmente se libera (es decir, se maneja), se muestra por segunda vez en los registros de acceso de nginx y en los registros de wordpress, pero los tiempos son diferentes.

Registros de acceso de nginx:

62.96.39.243 - - [17/Jan/2020:10:56:41 +0000] "GET /something

78.43.40.52 - - [17/Jan/2020:10:56:41 +0000] "POST /ajax-bidsform.html?meth=post&yid=d7f9f1a1a0bf HTTP/2.0" 200 208 "https://some.org/xchange_XRP_to_SBERRUB/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36" "-"

78.43.40.52 - - [17/Jan/2020:10:56:41 +0000] "GET /something

wordpress:

134.19.130.91 - - [17/Jan/2020:10:56:40 +0000] "GET /something

78.43.40.52 - - [17/Jan/2020:10:50:07 +0000] "POST /ajax-bidsform.html?meth=post&yid=d7f9f1a1a0bf HTTP/1.0" 200 559 "https://some.org/xchange_XRP_to_SBERRUB/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"

62.96.39.243 - - [17/Jan/2020:10:56:41 +0000] "GET /something

Como puede ver, POST /ajax-bidsform.html...el tiempo de colgar es de 10:56 en los registros de nginx, pero de 10:50 en wordpress, y este es exactamente el momento en que el cliente realizó esta solicitud. Hasta donde tengo entendido, esto significa que la solicitud se quedó atascada en algún lugar del nivel nginx durante casi 6 minutos hasta que realmente pasó a WordPress. Como puede ver, no tengo directivas de protección ddos ​​de nginx.

También algunas notas de mi parte: durante las solicitudes de suspensión no hay picos de CPU o RAM a largo plazo, por lo que probablemente no esté relacionado con problemas de hardware. También estaba pensando que de alguna manera está relacionado con el script colgado (es decir ajax-bidsform.html), pero comenzó a suceder solo cuando migramos a la instancia en la nube de Digital-Ocean desde el alojamiento virtual (donde nunca había sucedido antes), así que supongo que es un problema de configuración. La cronología de las solicitudes en los registros también es una prueba de ello.

Hasta ahora intenté:

  1. Aumentar worker_connectionsa 10000
  2. Aumente la instancia de nginx (no la del host) net.core.somaxconna 1024

Pero el problema sigue sucediendo. ¡Cualquier idea o pensamiento sería muy apreciado!

Respuesta1

10:56 en registros de nginx, pero 10:50 en wordpress

Interpretaría esto como que WordPress recibe la solicitud a las 10:50 y devuelve el resultado a nginx a las 10:56. Para estar seguro, puede agregar upstream_response_timeen log_formatnginx. VerUso del registro NGINX para monitorear el rendimiento de las aplicaciones.

información relacionada