Matar sockets abertos.

1. Matar sockets abertos.

Rafael Estefano
restefano

(usa Ubuntu)

Enviado em 14/03/2019 - 17:26h

Boa tarde colegas,

Tenho um servidor que roda uma aplicação antiga em java.
Essa aplicação recebe conexões via socket de outros equipamentos (fabricação própria) que se conectam através da rede gsm.
O problema é o seguinte...
Essa aplicação tem alguns furos que deixam sockets abertos no servidor até ele travar, esses problemas ocorrem principalmente por falha de conexão com os equipamentos.
Hoje como solução paliativa eu conto quantos sockets abertos existem para determinada porta e se tiverem mais que uma quantidade especifica eu mato a aplicação e subo ela novamente... assim todos os sockets são encerrados... mas isso também gera alguns problemas...
Aí vem a questão...
Gostaria de saber se existe uma forma de saber os sockets abertos, saber a quanto tempo eles estão abertos e matar esses sockets sem precisar reiniciar a aplicação,

Já dei uma boa pesquisada mas não cheguei perto de uma solução...

Sei que o correto é corrigir a aplicação, mas é um cenário bastante complexo...

Desde já, Obrigado.


  


2. Re: Matar sockets abertos.

Paulo
paulo1205

(usa Ubuntu)

Enviado em 15/03/2019 - 09:14h

Essas aplicações mal-escritas são mesmo uma praga. Qual problema você está tendo? Sockets TCP em estado CLOSE_WAIT (de comunicações que já acabaram, mas o cara simplesmente esqueceu de chamar close())? Sockets TCP em estado ESTABLISHED e com fila de recepção cheia e janela de recepção zerada, como se a aplicação tivesse esquecido que tem de consumir esses dados? Sockets UDP abertos a fim de fazer alguma consulta, que já tiveram pacotes enviados que podem ter sido perdidos, mas a aplicação nem retenta a consulta nem desiste de esperar por uma resposta que seguramente nunca virá?

Em qualquer um desses casos, o único jeito de se livrar desses sockets de modo limpo é, sim, corrigindo a aplicação. A segunda opção menos intrusiva é mesmo matar a instância em execução e a reiniciá-la.

Se você estiver disposto a experimentar — ou se gostar de viver perigosamente —, pode tentar interferir na execução da aplicação ativa através de uns truques de baixo nível, usando um depurador. Eu não conheço muito de Java, a ponto de saber se o Java Console ou algo semelhante poderia ser usado para injetar chamadas a métodos de fechamento de conexões, depois de identificar quais objetos detêm tais conexões. Mas com um depurador de baixo nível, como o gdb, pode ser que você consiga assumir o controle do processo (e.g. com “gdb -p pid_do_processo”) e então consiga injetar chamadas a close() (e.g. dentro do gdb, você poderia executar “call close()”), forçando o fechamento do socket em nível de processo do sistema operacional, não mais no nível de aplicação.

Dependendo de como a aplicação tenha sido programada e da frequência com que aconteçam as comunicações pela rede, pode ser que a operação acima seja relativamente indolor (o melhor cenário seria com tratadores de exceções nos lugares corretos e uma baixa frequência de comunicação, de modo que todo o processo de limpeza ocorra antes da próxima tentativa de comunicação; contudo se a aplicação tivesse sido bem programada, você não estaria tendo de fazer limpeza nenhuma). Mas não seria de espantar que uma forçação de fechamento do socket criasse um fluxo de execução inesperado para a aplicação. Outra possível consequência seria chegar uma conexão nova que acabe reaproveitando o número de descritor do socket você tiver fechado, e, ao mesmo tempo, a aplicação resolver reacordar o objeto que detém informações sobre o socket antigo, o que implicaria que haveria dois objetos diferentes controlando o mesmo recurso (o número do descritor do arquivo), com a possibilidade de um objeto interferir com o outro.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts