proxy_temp и редкие no such file or directory

Igor Sysoev is at rambler-co.ru
Thu Jan 15 16:36:04 MSK 2009


On Thu, Jan 15, 2009 at 03:08:20PM +0300, umask wrote:

> Добрый день,
> 
> столкнулись с такой ситуацией.
> 
> Имеем конфиг:
> 
> ..
> http {
> 	include       /etc/nginx/mime.types;
> 	default_type  text/plain;
> 
> 	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
> 			  '"$status" $body_bytes_sent "$http_referer" '
> 			  '"$http_user_agent" "$http_x_forwarded_for" "$http_cookie" '
> 			  '"$http_host" $request_time "$upstream_addr" [$upstream_response_time]';
> 
> 	# use as apache httpd compat logs
> 	log_format compat '$remote_addr - $remote_user [$time_local] "$request" '
> 			  '"$status" $body_bytes_sent "$http_referer" '
> 			  '"$http_user_agent" "$http_x_forwarded_for"';
> 
> 	access_log /var/log/nginx/access.log main;
> 	sendfile       on;
> 	tcp_nopush     on;
> 
> 	# http://sysoev.ru/web/upload.html
> 	lingering_time     30;
> 	lingering_timeout  5;
> 
> 	client_header_timeout  60;
> 	client_body_timeout    60;
> 	send_timeout           30;
> 
> 	client_max_body_size   16m;
> 
> 	large_client_header_buffers 8 32k;
> 
> 	keepalive_timeout  300 240;
> 
> 	reset_timedout_connection  on;
> 
> 	limit_zone   merging  $binary_remote_addr  16m;
> 
> 	server {
> 		listen 80 default backlog=1024 deferred;
> 		server_name .mydomain.ru .mydomain.net;
> 
> 		root /srv/www/xxx/htdocs/;
> 		index index.php;
> 
> 
> 		if ($http_host ~* www.mydomain.ru) {
> 			rewrite  ^ http://mydomain.ru$request_uri? permanent;
> 		}
> 
> 		if ($http_host ~* www.mydomain.net) {
> 			rewrite  ^ http://mydomain.net$request_uri? permanent;
> 		}
> 
> 
> 		if ($http_host !~* .*mydomain.*) {
> 			rewrite ^ http://mydomain.ru$request_uri? permanent;
> 		}

Вот это чудо нужно обрабатывать не if'ами, а в отдельных серверах:

      server {
          listen 80 default backlog=1024 deferred;
          server_name   *.mydomain.ru;
          rewrite  ^ http://mydomain.ru$request_uri? permanent;
      }

      server {
          listen 80;
          server_name   *.mydomain.net;
          rewrite  ^ http://mydomain.net$request_uri? permanent;
      }

      server {
          listen 80;
          server_name   mydomain.ru  mydomain.net;
          ...
      }

> 		location /admin {
>                         client_body_buffer_size  256k;
> 			proxy_buffering off;
>                         proxy_read_timeout    60;
> 			proxy_connect_timeout 3;
> 			proxy_pass   http://127.0.0.1:8080;
> 			proxy_set_header   X-Real-IP        $remote_addr;
> 			proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
> 			proxy_set_header   Host             $host;
> 		}
> 
> 		location / {
>                         client_body_buffer_size  256k;
>                         proxy_buffers 128 64k;
>                         proxy_read_timeout    60;
> 			proxy_connect_timeout 3;
> 			proxy_pass   http://127.0.0.1:8080;
> 			proxy_set_header   X-Real-IP        $remote_addr;
> 			proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
> 			proxy_set_header   Host             $host;
> 		}
> 
> 		location /merge.php {
> 			#access_log /tmp/merge1.log main;
> 			root /tmp/proxy_temp;
> 			error_page	404 = @fetch;
> 		}
> 
> 		location @fetch {
>                         # WARNING! We set limit_conn to prevent DoS for filesystem
>                         # files descriptors! Be ware!
> 			internal;
> 			access_log /tmp/merge2.log main;
>                         limit_conn         merging 2;
> 			proxy_pass         http://127.0.0.1:8080;
> 			proxy_temp_path    /tmp/proxy_temp;
> 			proxy_store        /tmp/proxy_temp/$request_uri;
> 			proxy_set_header   X-Real-IP        $remote_addr;
> 			proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
> 			proxy_set_header   Host             $host;
> 		}
> 
> 	}}
> 
> 
> Вся суть в последних 2-х локейшинах.
> Мы имеем в 1-м локейшене кэширование всего, что отдано по merge.php. Если в кэше нету запрошенного файла, то идём на бэкэнд и генерим там контект, сохраняем в кэше.
> Помимо всего прочего есть limit_conn во 2-м локейшене - чтобы 
> а) не долбить в бэкэнд, если будет DoS/DDoS (ибо merge.php собирает из нескольких .js один файл и это есть какие-то ресурсы).
> б) не сорить очень-очень сильно в файловой системе (ясное дело, что даже с двумя параллельными запросами можно очень быстно забить ФС, но если это делать в 100 раз быстрее, то до еженочной чистки proxy_temp можно не дожить).
> 
> 
> Всё работает по тестам отлично. Когда пришли юзеры в error-log'е стали редко появлятся вот такие сообщения:
> 2009/01/15 04:04:15 [error] 26040#0: *305905 open() "/tmp/proxy_temp/merge.php/--1230217985--style/analytics.css" failed (2: No such file or directory), client: 85.114.85.233, server: mydomain.ru, request: "GET /merge.php/--1230217985--style/analytics.css HTTP/1.1", host: "mydomain.ru", referrer: XXX

> всего 20 подобных ошибок на 170к запросов (170к - это вообще запросы на бэкэнд, а не в merge.php).
> 
> Включил уровень debug при логировании ошибок. Помимо всё тех же сообщений выше ничего дополнительного узнать не удалось.
> 
> 
> Кто-нибудь сталкивался с таким поведением?
> В чём проблема?

При первом обращении в лог пишется ошибка, что файл не найден.


-- 
Игорь Сысоев
http://sysoev.ru





More information about the nginx-ru mailing list