Re: снова про утечку сокетов

Maxim Dounin mdounin на mdounin.ru
Ср Июн 22 17:55:27 MSD 2011


Hello!

On Wed, Jun 22, 2011 at 09:51:23AM +0400, Костенко Евгений wrote:

> 22 июня 2011 г. 5:49 пользователь Maxim Dounin <mdounin at mdounin.ru> написал:
> 
> 
> > Аналогичный набор команд для gdb доступен по приведённой мной
> > ссылке в исходном треде:
> >
> > http://wiki.nginx.org/Debugging#Socket_leaks
> >
> > Там же есть инструкции, как получить идентификатор соединения
> > чтобы выцепить нужные данные из debug log'а.
> >
> 
> По этой ссылке и настраивал
> - собрал nginx с опцией debug
> - прописал в конфиге debug_points abort
> - для глобального error_log и для нужного хоста включал error_log на уровне
> debug

Если debug log уже был включён, то покажите 

fgrep '23887#0: *3682 ' /path/to/log

(где "23887" - pid процесса, 3682 - идентификатор соединения, 
полученный ниже в gdb)

> 
> 
> > Покажите сообщение об ошибке и имя используемого core-файла, дабы
> > не возникало сомнений в правильности выбора числа 34.
> >
> 
> Новые coredump'ы и большое количество жалоб на "open socket left in
> connection" появляются в большом количестве при рестарте.

Открытые сокеты проверяются при плавном завершении рабочего 
процесса, что случается после SIGQUIT или SIGHUP.  При нормальной 
работе таких alert'ов не будет, это ожидаемо.

> Помимо этого за прошедшую ночь появилось с десяток новых coredump'ов, но
> уже по сообщению "worker process N exited on signal 6 (core dumped)" и без
> упоминания сокетов.

А какие-нибудь alert'ы в логах при этом есть?  И хотелось бы 
увидеть backtrace из этих корок.

[...]

> в gdb, где 456 - номер соединения из строки лога про "open socket
> > #123 left in connection 456".
> >
> 
> Вывод указанных вами команд gdb
> 
> (gdb) set $c = &ngx_cycle->connections[34]
> (gdb) p $c->log->connection
> $6 = 3682
> (gdb) p *$c
> $7 = {data = 0x801884600, read = 0x809804ee0, write = 0x809a04ee0, fd = 31,
> recv = 0x43914c <ngx_unix_recv>, send = 0x439b00 <ngx_unix_send>, recv_chain
> = 0x439470 <ngx_readv_chain>, send_chain = 0x43f52c
> <ngx_freebsd_sendfile_chain>,
>   listening = 0x801844800, sent = 33580, log = 0x801de5360, pool =
> 0x801de5300, sockaddr = 0x801de5350, socklen = 16, addr_text = {len = 12,
> data = 0x801de5390 "41.202.20.82166"}, ssl = 0x0, local_sockaddr =
> 0x801b6dc60,
>   buffer = 0x801de5420, queue = {prev = 0x0, next = 0x0}, number = 3682,
> requests = 1, buffered = 16, log_error = 2, single_connection = 0,
> unexpected_eof = 0, timedout = 0, error = 1, destroyed = 0, idle = 0,
> reusable = 0, close = 0,
>   sendfile = 0, sndlowat = 0, tcp_nodelay = 0, tcp_nopush = 0, aio_sendfile
> = 0, busy_sendfile = 0x0}
> (gdb) set $r = (ngx_http_request_t *) $c->data
> (gdb) p *$r
> $8 = {signature = 1347703880, connection = 0x801e05a90, ctx = 0x801d2e410,
> main_conf = 0x801844df8, srv_conf = 0x8019c3120, loc_conf = 0x8019a6670,
> read_event_handler = 0x46d7a7
> <ngx_http_upstream_rd_check_broken_connection>,
>   write_event_handler = 0x470f3b <ngx_http_upstream_process_downstream>,
> cache = 0x801d31120, upstream = 0x801d2fb88, upstream_states = 0x801d2f518,

Здесь ещё пожалуйста

p *$r->upstream
p *$r->cache

И да, нужен debug log.  И хотелось бы увидеть конфиг.

[...]

> > Но скорее всего это ситуацию не прояснит, и нужен будет debug log
> > для соответствующих запросов.  Т.е. включать debug log и
> > "debug_points abort;", после появления сокетов в состоянии CLOSED
> > делать reload (можно - выключив debug log), потом получать в gdb
> > идентификатор соединения и смотреть логи.
> >
> 
> Количество сокетов в статусе CLOSED не имеет значения? Или необходимо
> дождаться существенно больших значений?

Нужен хотя бы один, явно в нём зависший (при обычной работе сокеты 
в состоянии CLOSED могут ненадолго появляться, это нормально).  
Для него должен быть alert про "open socket ..." при завершении 
процесса, дальше его исследовать.

Собственно, всё это нужно, чтобы малой кровью получить debug log 
для проблемного соединения.  Если нагрузка не очень большая и 
включение debug log'а проблем не вызывает - можно просто работать 
со включённым debug'ом.

> Еще один момент - при reload'е не происходит падения, либо появления новых
> coredump'ов.
> По крайней мере мои вчерашние и сегодняшние попытки спровоцировать падение
> через reload успехом не увенчались.

Как делается "reload" и "рестарт"?

Maxim Dounin



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