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.