Re: залипший сокет между nginx и fastcgi ?

Alexandre Snarskii snar на snar.spb.ru
Пт Дек 17 17:18:17 MSK 2010


On Fri, Dec 17, 2010 at 05:03:08PM +0300, Maxim Dounin wrote:
> Hello!
> 
> On Fri, Dec 17, 2010 at 03:57:49PM +0300, Alexandre Snarskii wrote:
> 
> > Дано: Linux (RHEL 5.4, 2.6.18-164.el5), nginx/0.8.53 "без посторонних
> > добавок", простенькая fcgi на базе обычного fastcgi devel kit 2.4.0,
> > основная fcgi - считать запрос, обработать, выдать x-accel-redirect
> > для проксирования на правильный target server. 
> > Общение nginx и fcgi - tcp на 127.0.0.1. 
> > 
> > Вроде бы все просто, хорошо и должно работать - nginx в любом
> > случае принимает запрос полностью и только потом отдает его 
> > на fastcgi_pass, так что на уровне fcgi можно верить что "медленных
> > клиентов не бывает" и использовать блокирующий интерфейс FCGX, 
> > но...
> > 
> > В некоторых случаях accept возвращает "нечитаемый" сокет, и fcgi 
> > тормозится на этапе: 
> > 
> > (gdb) where
> > #0  0x004db402 in __kernel_vsyscall ()
> > #1  0x006c38db in read () from /lib/libc.so.6
> > #2  0x00dd3feb in OS_Read (fd=54, buf=0x8c44118 "@Et", len=8192)
> >     at os_unix.c:460
> > #3  0x00dd12a0 in FillBuffProc (stream=0x8c36600) at fcgiapp.c:1636
> > #4  0x00dd1b82 in FCGX_Accept_r (reqDataPtr=0xb391f318) at fcgiapp.c:2208
> > #5  0x0804a119 in run (arg=0x8c2e3bc) at main.cc:91
> > #6  0x007545ab in start_thread () from /lib/libpthread.so.0
> > #7  0x006d2cfe in clone () from /lib/libc.so.6
> > 
> > и способна висеть в такой позе до рестарта, даже несмотря на 
> > то, что с другой стороны nginx уже давно сокет закрыл (connection
> > state CLOSE_WAIT). 
> > 
> > Вопрос вполне обычный - кто виноват и что делать ? :) 
> > Сменить OS/библиотеку/полностью переписать на scgi ? 
> 
> CLOSE_WAIT - со стороны fcgi?  Если при этом fcgi приложение 
> заблокировалось в read() (а не ест процессор, пытаясь звать read() 
> снова и снова), то это видимо race в ядре.  Ибо CLOSE_WAIT 
> означает, что ядро в курсе, что сокет с той стороны закрыли, и из 
> него больше ничего не прочитать, read() должен вернуться как 
> только выгребет всё из буфера.

Да, CLOSE_WAIT со стороны fcgi. Да, fcgi именно заблокировалось 
в read() а не поллит его. Да, read() в такой ситуации должен вернуть 
EOF или error, но, блин, не возвращает... 

-- 
In theory, there is no difference between theory and practice. 
But, in practice, there is. 



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