Soquetes encontrados pelo lsof mas não pelo netstat

15

Eu tenho um aplicativo que está ficando sem descritores de arquivos, aparentemente abrindo soquetes, mas não consigo descobrir exatamente o que esses soquetes fazem. Estes aparecem na saída lsof como

java    9689 appuser 1010u  sock       0,5          263746675 can't identify protocol
java    9689 appuser 1011u  sock       0,5          263746676 can't identify protocol
java    9689 appuser 1012u  sock       0,5          263746677 can't identify protocol
java    9689 appuser 1014u  sock       0,5          263746678 can't identify protocol
java    9689 appuser 1015u  sock       0,5          263746679 can't identify protocol
java    9689 appuser 1016u  sock       0,5          263746681 can't identify protocol

e em / proc / $ PID / fd como

lrwx------ 1 appuser appuser 64 Jun 23 11:49 990 -> socket:[263732085]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 991 -> socket:[263732086]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 992 -> socket:[263735307]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 993 -> socket:[263732088]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 995 -> socket:[263735308]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 996 -> socket:[263735309]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 997 -> socket:[263745434]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 998 -> socket:[263745435]
lrwx------ 1 appuser appuser 64 Jun 23 11:49 999 -> socket:[263745436]

mas não há saída semelhante em netstat -a .

O que são esses soquetes e como posso descobrir o que eles fazem?

Editar : Eu tentei executar grep $SOCKET /proc/net , como recomendado no lsof FAQ , onde $ SOCKET é, por exemplo, 263746679, mas isso também não deu resultados.

Como pano de fundo, o aplicativo é um contêiner para várias tarefas que, entre outras, executam chamadas de rede. Eu preciso destacar o que vai frenético, mas até eu descobrir com quem os sockets se comunicam, eu estou presa.

    
por Robert Munteanu 23.06.2010 / 14:07

3 respostas

16

Isso pode ocorrer se você criar um soquete, mas nunca conectar () ou vincular () a ele. Sua melhor aposta pode ser strace (-fF) o aplicativo e, em seguida, fazer referência cruzada com a saída de lsof para determinar quais soquetes estão causando o problema. Como um método bônus de depuração: se você enrolar suas chamadas de socket com informações de depuração e escrevê-las para / dev / null, elas aparecerão no strace sem fornecer arquivos de log hilariantemente grandes.

    
por 28.06.2010 / 15:43
2

Usando o Python, encontrei o mesmo problema em soquetes SSL:

  • Quando eu uso socket.close (), o soquete permanece no estado CLOSE_WAIT por um tempo indefinido
  • quando eu uso o socket.shutdown (), o lsof diz "não consigo identificar o protocolo"

A solução foi desdobrar a camada SSL antes de fechar:

  • origsock = socket.unwrap ()
  • origsock.close ()

Isso fecha os soquetes corretamente no meu aplicativo.

    
por 12.07.2010 / 13:47
1

A primeira coisa que eu faria seria aumentar o limite do descritor de arquivo:

~# vi /etc/sysctl.conf
fs.file-max = 331287

Em seguida, eu me certificaria de que seu sistema está atualizado, isso inclui todas as bibliotecas e servidores. É possível que seu servidor de aplicativos Java esteja desatualizado (se você estiver usando um). Também é possível que seu servidor de aplicativos esteja configurado incorretamente, você deve examinar seu arquivo de configuração e abaixar seu connectionTimeout e / ou seu maxKeepAliveRequests (não tenho certeza de qual servidor de aplicativos você está usando ou se você está usando um ...).

Não tenho certeza do que este aplicativo faz, mas se você não acha que ele requer dezenas de milhares de sockets, isso é quase certamente um "vazamento de descritor de arquivo" em seu aplicativo Java. Você pode ter que enviar um relatório de bug para o fornecedor. Neste relatório de bug, você deve incluir informações sobre como recriar o problema.

Aqui estão algumas maneiras de depurar o problema.

O Wireshark (ou twireshark para o cli) é a melhor ferramenta para ver como esses soquetes estão sendo usados. O Wireshark dará a você uma divisão do tipo de tráfego que está sendo jogado pelo fio. É provável que as primeiras poucas conexões sejam bem-sucedidas e, em seguida, atingirá o limite do descritor de arquivo. Uma vez que o limite do descritor de arquivo é atingido, então o Wireshark não vai pegar nada (e mais puro é o netstat), mas isso vai ajudar a diminuir o problema. Há talvez casos em que muitos SYNs de saída estão sendo enviados, no entanto, nenhum SYN / ACK está sendo recebido, portanto, muitas conexões tcp estão apenas presas no estado SYN_WAIT.

Se você tiver acesso ao código fonte e souber o tipo de soquetes que está sendo criado (como usar strace ou apenas pesquisar o código), abra o projeto no Eclipse (ou outro IDE) e defina um ponto de interrupção em a função que está criando esses soquetes. Quando o ponto de interrupção é atingido, você pode ver o rastreamento de pilha. Esse vazamento de descritor de arquivo talvez seja um loop infinito simples ou talvez o valor de tempo limite do soquete seja muito grande. Outra possibilidade é que o aplicativo java não esteja fazendo um socket.close() para limpar as conexões. Fazer um fechamento geralmente é feito no bloco finely de try/catch (Sim, um soquete deve sempre ter um try / catch em Java ou não será construído :). No final do dia, é provável que o aplicativo Java não esteja manipulando corretamente sua IOException.

    
por 30.06.2010 / 00:09