Eu tenho um aplicativo que está ficando sem descritores de arquivo, aparentemente abrindo soquetes, mas não consigo descobrir exatamente o que esses soquetes fazem. Eles 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?
Edit : Eu tentei rodar grep $SOCKET /proc/net
, como recomendado nas FAQs lsof , 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, realizam chamadas de rede. Eu preciso destacar o que fica furioso, mas até descobrir com quem essas tomadas se comunicam, eu estou preso.
Respostas:
Isso pode ocorrer se você criar um soquete, mas nunca conectar () ou vincular () a ele. Sua melhor aposta pode ser rastrear (-fF) o aplicativo e 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ê agrupar suas chamadas de soquete com informações de depuração e gravá-las em / dev / null, elas aparecerão estritamente sem fornecer arquivos de log hilariamente grandes.
fonte
Usando o Python, encontrei o mesmo problema nos soquetes SSL:
A solução foi desembrulhar a camada SSL antes de fechar:
Isso fecha os soquetes corretamente no meu aplicativo.
fonte
A primeira coisa que eu faria é incrementar se o descritor do seu arquivo limitar:
Em seguida, verifique se o seu sistema está atualizado, incluindo 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 diminuir seu
connectionTimeout
e / ou seumaxKeepAliveRequests
(não tenho certeza de qual servidor de aplicativos você está usando ou se você está usando um ...).Não sei ao certo o que esse aplicativo faz, mas se você acha que não requer dezenas de milhares de soquetes, é quase certamente um "vazamento de descritor de arquivo" no aplicativo Java. Pode ser necessário enviar um relatório de bug ao 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 mostra a você o tipo de tráfego que está sendo jogado pela rede. É provável que as primeiras conexões sejam bem-sucedidas e atinja o limite do descritor de arquivo. Quando o limite do descritor de arquivo for atingido, o Wireshark não perceberá nada (e mais limpo é o netstat), mas isso ajudará a diminuir o problema. Talvez haja um caso em que muitos SYNs de saída estejam sendo enviados, no entanto, nenhum SYN / ACK esteja sendo recebido, portanto, muitas conexões tcp ficam presas no estado SYN_WAIT.
Se você tiver acesso ao código-fonte e souber o tipo de soquetes que estão sendo criados (como usar strace ou apenas pesquisar o código), poderá abrir o projeto no Eclipse (ou outro IDE) e definir um ponto de interrupção na função que está criando esses soquetes. Quando o ponto de interrupção é atingido, você pode observar o rastreamento da pilha. Esse descritor de arquivo vaza talvez um loop infinito simples ou talvez o valor do tempo limite do soquete seja muito grande. Outra possibilidade é que o aplicativo java não esteja
socket.close()
limpando as conexões. Fazer um fechamento é geralmente feito nofinely
bloco de atry/catch
(Sim, um soquete deve sempre ter uma tentativa / captura em Java ou não será construído :). No final do dia, é provável que o aplicativo Java não esteja lidando adequadamente com as IOException.fonte