Maison développement back-end Golang Utiliser le modèle Heartbeats dans Golang

Utiliser le modèle Heartbeats dans Golang

Nov 03, 2024 am 06:08 AM

Utilizando o pattern Heartbeats em Golang

Implémentation de Heartbeats dans Go pour la surveillance des applications

Au cours de mes aventures en équilibrage Data & Software Engineer, je cherche toujours quelque chose d'un peu différent dans GoLang pour étudier, comprendre son fonctionnement et l'appliquer à des choses plus complexes que certains cours et articles traditionnels de base que je trouve sur Internet. . Dans ce court article, je vais rapporter et démontrer comment j'ai implémenté via Go Routines, le package time utilisant Ticker pour simuler le battement de coeur ("Je suis vivant") de l'application, en plus de l'utilisation des canaux, etc.

Ce n'est pas une nouveauté pour beaucoup qu'il soit extrêmement important de s'assurer que quiconque appelle une certaine fonction sache si la fonction prend du temps, est en cours de traitement ou est verrouillée. Cela dit, plusieurs autres terminologies ont émergé telles que Trace, Metrics, connectivité, etc., qui ont été introduites dans les applications de surveillance qui utilisent dans la plupart des cas des agents installés sur les serveurs d'applications qui collectent les métriques et les envoient à des interfaces qui visualisent toutes (ou presque) le statut de votre candidature. Parmi ces outils nous avons DataDog, NewRelic, Slack, Grafana, Jaeger, etc.

Qu'aurons-nous ici ?

Alors que j'étudie et réfléchis à la création de quelque chose de rapide et simple qui aborde des concepts Go plus avancés, j'ai créé une application relativement simple qui utilise le modèle de battements de cœur. Celui qui m'appelle reçoit le résultat et, en même temps, l'information si je suis toujours actif ou non. Dans un scénario plus avancé, cela peut être intéressant pour personnaliser ce qui est réellement une application active en fonction de certaines particularités métier, puisqu'une simple implémentation d'un Prometheus résout ce cas (l'application est-elle active ? CPU, Mémoire, goroutines ouvertes), mais pas avec des commentaires simultanés et personnalisables.

Heure de Code !

En termes de structure, je n'ai créé que trois fichiers au sein de mon package avec go mod :

  • Dictionary.go : contient un dictionnaire de noms pour la fonction à rechercher.
  • task.go : Tâche qui contient la fonction d'analyser les noms du dictionnaire et, en même temps, d'informer s'il est actif ou non via le rythme de la chaîne de team.Ticker.
  • task_test.go : effectue un test unitaire de la fonction présente dans task.go pour voir à la fois la réponse des données du dictionnaire et également des informations indiquant si l'application est toujours active !

dictionnaire.go

Cette partie du code Go définit une variable appelée « dictionnaire » qui est une carte qui associe des caractères de type rune à des chaînes.

Chaque entrée de carte est une clé (rune) et une valeur (chaîne). Dans l'exemple ci-dessous, les touches sont des lettres minuscules de l'alphabet et les valeurs sont des noms associés à chaque lettre. Par exemple, la lettre « a » est associée au nom « airton », la lettre « b » est associée au nom « bruno », et ainsi de suite :

package heartbeat

var dicionario = map[rune]string{
    'a': "airton",
    'b': "bruno",
    'c': "carlos",
    'd': "daniel",
    'e': "eduardo",
    'f': "felipe",
    'g': "gustavo",
}
Copier après la connexion
Copier après la connexion

tâche.go

J'explique mieux ci-dessous après le code complet chaque partie du code :

package heartbeat

import (
    "context"
    "fmt"
    "time"
)

func ProcessingTask(
    ctx context.Context, letras chan rune, interval time.Duration,
) (<-chan struct{}, <-chan string) {

    heartbeats := make(chan struct{}, 1)
    names := make(chan string)

    go func() {
        defer close(heartbeats)
        defer close(names)

        beat := time.NewTicker(interval)
        defer beat.Stop()

        for letra := range letras {
            select {
            case <-ctx.Done():
                return
            case <-beat.C:
                select {
                case heartbeats <- struct{}{}:
                default:
                }
            case names <- dicionario[letra]:
                lether := dicionario[letra]
                fmt.Printf("Letra: %s \n", lether)

                time.Sleep(3 * time.Second) // Simula um tempo de espera para vermos o hearbeats
            }
        }
    }()

    return heartbeats, names
}
Copier après la connexion

Importer des dépendances

package heartbeat

import (
    "context"
    "fmt"
    "time"
)
Copier après la connexion

Ici, j'ai mon package Heartbeat qui sera chargé d'implémenter une fonctionnalité qui envoie des « battements de cœur » à un intervalle de temps spécifique, lors du traitement des tâches. Pour cela, j'ai besoin de contexte (Context Management), de fmt (pour le formatage des chaînes) et de time pour le contrôle du temps.

Définition de la fonction initiale

func ProcessingTask (
    ctx context.Context, letras chan rune, interval time.Duration,
) (<-chan struct{}, <-chan string) {
Copier après la connexion

C'est la définition de la fonction ProcessingTask qui prend un contexte ctx, un canal de lettres (un canal qui reçoit des caractères Unicode) et un intervalle de temps comme arguments. La fonction renvoie deux canaux : un canal de battements de cœur qui envoie une structure vide pour chaque « battement de cœur » et un canal de noms qui envoie le nom de la lettre correspondant à chaque caractère reçu.

Canaux

heartbeats := make(chan struct{}, 1)
names := make(chan string)
Copier après la connexion

Ces deux lignes créent deux canaux : heartbeats est un canal tampon d'une capacité d'un élément et names est un canal sans tampon.

Go Routine qui fait le gros du travail

go func() 
    defer close(heartbeats)
    defer close(names)

    beat := time.NewTicker(interval)
    defer beat.Stop()

    for letra := range letras {
        select {
        case <-ctx.Done():
            return
        case <-beat.C:
            select {
            case heartbeats <- struct{}{}:
            default:
            }
        case names <- dicionario[letra]:
            lether := dicionario[letra]
            fmt.Printf("Letra: %s \n", lether)

            time.Sleep(3 * time.Second) // Simula um tempo de espera para vermos o hearbeats
        }
    }
}()

return heartbeats, names
Copier après la connexion

Il s'agit d'une goroutine anonyme (ou fonction anonyme qui s'exécute dans un nouveau thread) qui exécute la logique principale de la fonction ProcessingTask. Il utilise une boucle for-range pour lire les caractères du canal des lettres. Dans la boucle, utilisez une sélection pour choisir une action à effectuer parmi les options disponibles :

  • case <-ctx.Done() : Si le contexte est annulé, la fonction se termine immédiatement, en utilisant l'instruction return.
  • case <-beat.C : Si le ticker de battement envoie une valeur, la goroutine essaie d'envoyer une structure vide au canal des battements de cœur en utilisant une sélection avec une valeur par défaut vide.
  • noms de cas <- dictionnaire[lettre] : si une lettre est reçue, la goroutine obtient le nom de la lettre correspondante à partir du dictionnaire dictionnaire, l'envoie au canal des noms, imprime la lettre à l'écran à l'aide du package fmt et attend trois secondes avant de passer au caractère suivant. Cette attente simulée permet de voir les « battements de cœur » envoyés.

Enfin, la fonction renvoie les battements de cœur et nomme les canaux.

Tester l'application

task_test.go

package heartbeat

var dicionario = map[rune]string{
    'a': "airton",
    'b': "bruno",
    'c': "carlos",
    'd': "daniel",
    'e': "eduardo",
    'f': "felipe",
    'g': "gustavo",
}
Copier après la connexion
Copier après la connexion

Ici, j'ai créé un test unitaire Go pour la fonction ProcessingTask qui a été expliquée précédemment. La fonction de test TestProcessingTask crée un contexte avec un délai d'attente de 20 secondes et un canal de caractères Unicode (lettres). La goroutine anonyme envoie ensuite les paroles au canal des paroles. La fonction ProcessingTask est ensuite appelée avec le contexte, le canal de caractères Unicode et un intervalle de temps. Il renvoie deux canaux, un canal de battement de cœur et un canal de mots.

La fonction de test exécute ensuite une boucle infinie avec une sélection, qui lit à partir de trois canaux : le contexte, le canal de battement de cœur et le canal de mots.

Si le contexte est annulé, la boucle de test est terminée. Si un battement de cœur est reçu, un message « Application Up ! » est imprimé sur une sortie standard. Si un mot est reçu, le test vérifie si le mot est présent dans le dictionnaire de lettres. S'il n'est pas présent, le test échoue et un message d'erreur s'affiche.

Par conséquent, ce test unitaire teste notre fonction ProcessingTask, qui reçoit des caractères d'un canal, envoie des noms de lettres à un autre canal et émet les « battements de cœur » lors de son exécution dans un contexte dans lequel j'ai utilisé une limite de temps. Ahhh... et il vérifie aussi si les noms des lettres envoyées au canal de mots sont présents dans le dictionnaire.

Mes conclusions

Ce code Go illustre quelques concepts importants du langage Go et des tests unitaires :

  • Contexte
  • Goroutines
  • Chaînes
  • Tests unitaires (utilisation de la sélection pour surveiller plusieurs canaux)

Projet complet sur mon GitHub : https://github.com/AirtonLira/heartbeatsGolang

LinkedIn - Airton Lira Junior

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

<🎜>: Grow A Garden - Guide de mutation complet
3 Il y a quelques semaines By DDD
<🎜>: Bubble Gum Simulator Infinity - Comment obtenir et utiliser les clés royales
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Système de fusion, expliqué
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Comment déverrouiller le grappin
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel Java
1666
14
Tutoriel PHP
1273
29
Tutoriel C#
1254
24
Golang vs Python: performance et évolutivité Golang vs Python: performance et évolutivité Apr 19, 2025 am 12:18 AM

Golang est meilleur que Python en termes de performances et d'évolutivité. 1) Les caractéristiques de type compilation de Golang et le modèle de concurrence efficace le font bien fonctionner dans des scénarios de concurrence élevés. 2) Python, en tant que langue interprétée, s'exécute lentement, mais peut optimiser les performances via des outils tels que Cython.

Golang et C: concurrence vs vitesse brute Golang et C: concurrence vs vitesse brute Apr 21, 2025 am 12:16 AM

Golang est meilleur que C en concurrence, tandis que C est meilleur que Golang en vitesse brute. 1) Golang obtient une concurrence efficace par le goroutine et le canal, ce qui convient à la gestion d'un grand nombre de tâches simultanées. 2) C Grâce à l'optimisation du compilateur et à la bibliothèque standard, il offre des performances élevées près du matériel, adaptées aux applications qui nécessitent une optimisation extrême.

Partage avec Go: un guide du débutant Partage avec Go: un guide du débutant Apr 26, 2025 am 12:21 AM

GOISIDEALFORBEGINNERNERS et combinant pour pourcloudandNetWorkServicesDuetOtssimplicity, Efficiency, andCurrencyFeatures.1) InstallgofromTheofficialwebsiteandverifywith'goversion'..2)

Golang vs C: Performance et comparaison de la vitesse Golang vs C: Performance et comparaison de la vitesse Apr 21, 2025 am 12:13 AM

Golang convient au développement rapide et aux scénarios simultanés, et C convient aux scénarios où des performances extrêmes et un contrôle de bas niveau sont nécessaires. 1) Golang améliore les performances grâce à des mécanismes de collecte et de concurrence des ordures, et convient au développement de services Web à haute concurrence. 2) C réalise les performances ultimes grâce à la gestion manuelle de la mémoire et à l'optimisation du compilateur, et convient au développement du système intégré.

Impact de Golang: vitesse, efficacité et simplicité Impact de Golang: vitesse, efficacité et simplicité Apr 14, 2025 am 12:11 AM

GOIMIMPACTSDEVENCEMENTSPOSITIVEMENTS INSPECT, EFFICACTION ET APPLICATION.1) VITESSE: GOCOMPILESQUICKLYANDRUNSEFFIÉMENT, IDEALFORLARGEPROROSTS.2) Efficacité: ITSCOMPEHENSIVESTANDARDLIBRARYREDUCEEXTERNEDENDENCES, EnhancingDevelovefficiency.3) Simplicité: Simplicité: Implicité de la manière

C et Golang: Lorsque les performances sont cruciales C et Golang: Lorsque les performances sont cruciales Apr 13, 2025 am 12:11 AM

C est plus adapté aux scénarios où le contrôle direct des ressources matérielles et une optimisation élevée de performances sont nécessaires, tandis que Golang est plus adapté aux scénarios où un développement rapide et un traitement de concurrence élevé sont nécessaires. 1.C's Avantage est dans ses caractéristiques matérielles proches et à des capacités d'optimisation élevées, qui conviennent aux besoins de haute performance tels que le développement de jeux. 2. L'avantage de Golang réside dans sa syntaxe concise et son soutien à la concurrence naturelle, qui convient au développement élevé de services de concurrence.

Golang vs Python: différences et similitudes clés Golang vs Python: différences et similitudes clés Apr 17, 2025 am 12:15 AM

Golang et Python ont chacun leurs propres avantages: Golang convient aux performances élevées et à la programmation simultanée, tandis que Python convient à la science des données et au développement Web. Golang est connu pour son modèle de concurrence et ses performances efficaces, tandis que Python est connu pour sa syntaxe concise et son écosystème de bibliothèque riche.

Golang et C: les compromis en performance Golang et C: les compromis en performance Apr 17, 2025 am 12:18 AM

Les différences de performance entre Golang et C se reflètent principalement dans la gestion de la mémoire, l'optimisation de la compilation et l'efficacité du temps d'exécution. 1) Le mécanisme de collecte des ordures de Golang est pratique mais peut affecter les performances, 2) la gestion manuelle de C et l'optimisation du compilateur sont plus efficaces dans l'informatique récursive.

See all articles