Servidores de aplicativos como o Tomcat não gostam se os webapps se comportarem mal (fazendo coisas desagradáveis com carregadores de classes, vazamentos de memória, iniciando threads não pertencentes ao daemon, etc.) para que não possam ser desligados apropriadamente quando solicitados.
Em primeiro lugar, para reiniciar o Tomcat da maneira mais difícil, pode ser a coisa "certa" a ser feita para manter as operações em execução até que o aplicativo possa ser corrigido. A próxima coisa é aumentar o nível de log e checar os arquivos de log para pontos obious como OutOfMemoryErrors, etc. Se você tiver sorte, o webapp usa logging e pode apontar o que está fazendo.
A próxima coisa é anexar um agente de monitoramento (visualvm.dev.java.net está fazendo um ótimo trabalho) para a instância do Tomcat. Você precisa ativar o JMX no lado do servidor antes de poder se conectar remotamente. Se você estiver usando o Suse Linux ou semelhante, não se esqueça de configurar o nome do host rmi do servidor como propriedade do sistema. Assista ao consumo de memória, retire os encadeamentos quando os servidores travam. Quando você emite um pedido de desligamento com shutdown.sh
e o servidor não desliga corretamente, faça um dump de encadeamento e veja quais encadeamentos estão sendo executados e em qual classe / método eles estão agora.
Se houver algo errado com a memória, você pode querer tentar ajustar as configurações do coletor de lixo para a JVM ou usar outra JVM como o JRockit. Usar um GC mais agressivo pode ajudar.
Outra maneira é impedir que o aplicativo faça o que fizer de errado - use um Gerenciador de Segurança e ajuste o arquivo de política de segurança até que o aplicativo esteja funcionando. Pode revelar que o aplicativo está fazendo algo que não deveria fazer em primeiro lugar.