2017-06-11 3 views
2

J'ai une application Spring Boot fonctionnant sur deux serveurs. Il accepte le fichier demandes de téléchargement (environ 1 Ko) via le contrôleur à partir de milliers de périphériques IOT.L'application Spring Boot se fige après un jour

En outre, il existe un TCP Listener qui accepte également les données GPS en tant que flux provenant de ces périphériques IOT.

J'ai configuré le nombre de threads max Tomcat à 3000 sur un serveur et 5000 sur une machine virtuelle plus grande. Au bout d'un jour ou deux, mon application Spring Boot se bloque, c'est-à-dire qu'elle cesse de répondre à d'autres appels API.

Une raison, je soupçonne est que les périphériques IOT sont ne fermant pas la connexion socket TCP après l'envoi des données.

Où pourrais-je me tromper? Je manque de threads pour gérer les nouvelles demandes entrantes?

############################

EDIT 1:

Après avoir enquêté sur la thread dump et l'ajout de journaux pendant la connexion Socket et la fermeture, j'ai découvert que le périphérique IOT ne ferme pas les connexions. Au lieu de cela, le périphérique crée une nouvelle connexion chaque fois qu'il veut envoyer de nouvelles données sans fermer la précédente. Avant la fermeture de l'application, 22500 connexions ouvertes étaient automatiquement fermées.

Comment puis-je gérer ce comportement? Dois-je fermer les connexions avec force après un certain délai?

+0

La première chose à faire est de regarder n'importe quelle surveillance disponible. Spring Boot offre la bibliothèque d'actionneurs. L'avez-vous activé dans votre application? Il devrait déjà offrir des paramètres de pool ootb. – dunni

+1

Un vidage de thread vous permettra de savoir si vous manquez de threads –

+0

@dunni Merci. Je ne le savais pas. Je vais le mettre en place et vous le faire savoir. – amitection

Répondre

1

Vous pouvez atténuer le problème des connexions inactives en cachant votre service derrière un Nginx ou HAProxy qui ferme les connexions inactives par défaut après un délai d'attente donné.

Une autre option consiste à définir server.connection-timeout dans les propriétés de l'application (voir server properties), mais cela semble être applicable uniquement à HTTP.

+0

Je connais 'server.connection-timeout'. J'ai défini le délai d'attente de socket dans 'TcpNetServerConnectionFactory' et cela fonctionne. Pour le faire de manière plus efficace, je pensais à maintenir une carte de IOT_DEVICE_ID: Connection_Id et si plusieurs connexions sont reçues du même périphérique, je vais fermer le précédent de manière forcée. – amitection

+0

@amitection Je dirais que votre cas est l'une des raisons pour lesquelles HAProxy existe. Comme un avantage, vous aurez également l'équilibrage de la charge lorsque votre service va aller en cluster. – jihor

+0

J'ai mes machines virtuelles sur Azure derrière un équilibreur de charge. Mais merci. Je vais regarder dans HAProxy – amitection