j'ai écrit un programme de collecte de journal en déplacement, qui gère un tas de goroutines comme suit:golang: comment déboguer état de course possible
- routine A exécute serveur HTTP, permet aux utilisateurs d'afficher les informations du journal
- la routine B exécute le serveur UDP, permet aux messages de journal d'être envoyés à partir de LAN
- routine C exécute un temporisateur, qui interroge/télécharge périodiquement des archives de journal zippées à partir d'un serveur de fichiers HTTP interne (ne fait pas partie du programme)
- routine B & C à la fois envoyer des messages traités à un canal 0 La routine D exécute une boucle for for {} avec une instruction select qui reçoit un message du canal et le vide sur le disque
- il existe quelques autres routines go comme une routine pour analyser les archives de journal générées par la routine D vers Créer des index SQLite etc.
Le programme rencontre un problème: après quelques heures d'exécution, le serveur HTTP de visionneuse de journal fonctionne toujours correctement, mais aucun message ne provient des routines UDP ou fileserver. Je sais qu'il y a des messages de journal sans fin envoyant à partir de différents canaux, aussi si je redémarre le programme, il commence à traiter les journaux entrants à nouveau.
J'ai ajouté -race au compilateur, et en effet trouver un code problématique, et j'ai corrigé ces, mais toujours, le problème persiste. De plus, bien qu'il y ait des problèmes racistes, l'ancien code de version qui s'exécute sur notre serveur de production fonctionne bien, quel que soit le code racé.
Ma question est, comment puis-je procéder pour localiser le problème. Ce qui suit est la boucle de clé dans ma routine de traitement de journal:
for {
select {
case msg := <-logCh:
logque.Cache(msg)
case <-time.After(time.Second):
}
if time.Since(lastFlush) >= 3 * time.Second {
logque.Flush()
lastFlush = time.Now()
}
}
Regardez une trace de la pile lorsque le serveur cesse de fonctionner et de voir où chaque goroutine est bloqué. – JimB
comment regarder trace de la pile pendant que le programme fonctionne bien? Notez que rien ne semble être faux, juste que la routine de minuterie n'imprime pas de message pendant qu'elle est déclenchée, et que le serveur UDP cesse de recevoir des messages, et rien n'a été produit sur la console – xrfang
Vous pouvez envoyer un SIGQUIT pour quitter avec une trace de pile, configurer un Gestionnaire http ou gestionnaire de signal pour en imprimer un à la demande, utiliser le point de terminaison pprof goroutine, etc. Vos goruotines sont bloquées pour une raison quelconque, vous voulez donc voir pourquoi. – JimB