client closed prematurely connection в режиме proxy

Sergey Kobzar sergey.kobzar на itcraft.org
Пт Апр 27 10:46:30 UTC 2012


Nginx в режиме прокси (фронтэнд):

user nginx nginx;
worker_processes 24;

error_log /var/log/nginx/error.log info;


events {
         worker_connections 1024;
         use epoll;
}


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

         log_format main
                 '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 '"$gzip_ratio" '
                 '$upstream_addr $upstream_status';

         client_header_timeout 10m;
         client_body_timeout 10m;
         keepalive_timeout 75 20;
         send_timeout 10m;
         server_tokens off;
         client_max_body_size 40m;

         sendfile on;
         tcp_nopush on;

         proxy_buffer_size 128k;
         proxy_buffers 8 64k;
         proxy_connect_timeout 5;
         proxy_intercept_errors on;

         set_real_ip_from 127.0.0.1;
         real_ip_header X-Real-IP;


         upstream backend {
                 server 10.17.92.2  max_fails=3 fail_timeout=300s;
                 server 10.17.92.12 max_fails=3 fail_timeout=300s;
                 server 127.0.0.1 backup;
                 ip_hash;
         }

         upstream backend_static {
                 server 10.17.92.2  max_fails=3 fail_timeout=300s;
                 server 10.17.92.12 max_fails=3 fail_timeout=300s;
                 server 127.0.0.1 backup;
         }


         server {
                 listen 127.0.0.1;
                 server_name localhost;

                 access_log /var/log/nginx/localhost_access.log main;
                 error_log /var/log/nginx/localhost_error.log info;

                 location / {
                         error_page 502 504 /errors/500.html;
                         return 500;
                 }

                 location ^~ /errors/ {
                         root /home/www/localhost/htdocs;
                         expires max;
                 }
         }


         server {
                 listen 80 default;
                 server_name localhost;

                 access_log /var/log/nginx/default_access.log main;
                 error_log /var/log/nginx/default_error.log info;

                 location / {
                         proxy_pass http://backend;

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

                 error_page 500 502 504 /errors/500.html;

                 location ^~ /errors/ {
                         root /home/www/localhost/htdocs;
                         expires max;
                 }
         }


На фронтэнде:
66.249.73.15 - - [27/Apr/2012:11:23:22 +0100] "GET ... HTTP/1.1" 504 
9700 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; 
+http://www.google.com/bot.html)" "-" 10.17.92.12:80, 10.17.92.2:80 504, 504
66.249.73.209 - - [27/Apr/2012:11:23:23 +0100] "GET ... HTTP/1.1" 504 
9700 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; 
+http://www.google.com/bot.html)" "-" 10.17.92.12:80, 10.17.92.2:80 504, 504
66.249.73.15 - - [27/Apr/2012:11:23:23 +0100] "GET ... HTTP/1.1" 500 
9676 "-" "SAMSUNG-SGH-E250/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 
UP.Browser/6.2.3.3.c.1.101 (GUI) MMP/2.0 (compatible; 
Googlebot-Mobile/2.1; +http://www.google.com/bot.html)" "-" 127.0.0.1:80 500


На бэкенде на тот же запрос:
access log:
66.249.73.15 - - [27/Apr/2012:11:23:22 +0100] "GET ... HTTP/1.0" 499 0 
"-" "Mozilla/5.0 (compatible; Googlebot/2.1; 
+http://www.google.com/bot.html)" "-"

error_log:
2012/04/27 11:23:22 [info] 9804#0: *206566 client closed prematurely 
connection, so upstream connection is closed too while sending request 
to upstream, client: 66.249.73.15, server: localhost, request: "GET ... 
HTTP/1.0", upstream: "fastcgi://127.0.0.1:9001", host: "www.test.com"


Т.е. общая картина:

1. Клиент закрыл соединение - на бэкенде получили 499
2. Вернули фронтенду 504
3. 3 подобные ситуации и бэкэнд выкидываем из пула

Как-то это неправильно IMO. Т.е. несколько клиентов закрывших соединение 
могут завалить всю систему. Уменьшать max_fails=3 fail_timeout=300s не 
хочу, т.к если один из бэкжндов действительно в дауне, начинаются проблемы.

Как правильно решить подобную ситуацию?


Спасибо.



Подробная информация о списке рассылки nginx-ru