Maison >développement back-end >Golang >Comment mettre en œuvre la surveillance des processus dans Golang

Comment mettre en œuvre la surveillance des processus dans Golang

PHPz
PHPzoriginal
2023-04-24 09:10:261951parcourir

En matière de développement, d'exploitation et de maintenance, nous devons souvent surveiller les processus pour nous assurer qu'ils peuvent fonctionner normalement et que les problèmes peuvent être détectés et traités en temps opportun lorsqu'ils surviennent. Dans cet article, nous présenterons comment utiliser le langage Go pour mettre en œuvre la surveillance des processus, vous aidant ainsi à mieux comprendre et appliquer la technologie de surveillance.

1. Principes de base de la surveillance des processus

La surveillance des processus fait principalement référence à une technologie de surveillance, de contrôle et de gestion des exceptions de l'état d'exécution des applications. En termes simples, il s'agit d'utiliser certaines méthodes de surveillance pour surveiller l'état d'exécution du programme en temps réel, tout en garantissant que le programme s'exécute normalement et peut gérer les erreurs en temps opportun.

Dans la surveillance des processus, la méthode de surveillance la plus couramment utilisée est le mécanisme du rythme cardiaque. Le mécanisme dit de battement de cœur consiste à envoyer en permanence des messages à l'extérieur pendant l'exécution du programme pour indiquer son état de fonctionnement normal. Et nous déterminons si le programme est sain en capturant et en analysant ces messages. Une fois qu'une anomalie de programme est découverte, elle sera traitée en conséquence pour assurer le fonctionnement normal du système.

2. L'idée d'implémentation de la surveillance des processus dans Golang

En langage Go, nous pouvons utiliser des packages prêts à l'emploi pour implémenter la surveillance des processus. Les étapes spécifiques de mise en œuvre sont les suivantes :

1. Obtenez toutes les informations sur les processus

Nous pouvons utiliser le package de processus dans le package psutil pour obtenir des informations pertinentes sur tous les processus du système. Tout d'abord, nous devons introduire le package :

import (
    "github.com/shirou/gopsutil/process"
)

Ensuite, récupérez tous les processus du système en appelant la fonction process.Processes() :

processes, err := process.Processes()
if err != nil {
    log.Fatalf("failed to get all processes: %v", err)
}

Cette fonction renvoie une tranche de processus, dont chaque élément est un processus contenant un processus Structure des informations. Pour les structures spécifiques, veuillez vous référer à la documentation officielle de psutil.

2. Filtrer les processus qui doivent être surveillés

Afin de surveiller un processus spécifique, nous devons trouver le processus qui nous intéresse parmi tous les processus et enregistrer ses pid. Ici, nous pouvons utiliser des filtres conditionnels pour filtrer rapidement les processus qui doivent être surveillés. Par exemple, nous pouvons filtrer les processus dont nous avons besoin en fonction du nom du processus, de l'ID du processus et d'autres conditions. En prenant le nom du processus comme exemple, le code est le suivant :

targetProcessName := "myApp"
targetPidList := make([]int32, 0)

for _, proc := range processes {
    name, err := proc.Name()
    if err != nil || name != targetProcessName {
        continue
    }
    pid := proc.Pid
    targetPidList = append(targetPidList, pid)
    log.Printf("find target process %s, pid = %d\n", name, pid)
}

3. Effectuez une détection de battement de cœur sur le processus qui doit être surveillé

Pour le processus qui doit être surveillé, nous pouvons déterminer s'il fonctionne normalement en lui envoyer un message de battement de cœur. Plus précisément, nous pouvons porter un jugement en lisant son utilisation du processeur et de la mémoire. Si vous constatez une utilisation anormale du processeur et de la mémoire, vous pouvez penser qu’il y a un problème avec le processus.

Afin d'implémenter la détection des battements cardiaques, nous pouvons utiliser une goroutine pour lire périodiquement l'état du processus spécifié et l'enregistrer. Le code d'implémentation spécifique est le suivant :

type ProcessState struct {
    CpuPercent    float64
    MemResident   uint64
    MemVirtual    uint64
    MemSwap       uint64
}

func checkProcessState(targetPid int32, stateChan chan<- ProcessState) {
    ticker := time.NewTicker(5 * time.Second)
    for {
        select {
        case <-ticker.C:
            proc, err := process.NewProcess(targetPid)
            if err != nil {
                log.Printf("failed to get process %d: %v", targetPid, err)
                continue
            }
            cpuPercent, err := proc.CPUPercent()
            if err != nil {
                log.Printf("failed to get cpu percent for process %d: %v", targetPid, err)
                continue
            }
            memInfo, err := proc.MemoryInfo()
            if err != nil {
                log.Printf("failed to get memory info for process %d: %v", targetPid, err)
                continue
            }
            state := ProcessState{
                CpuPercent:  cpuPercent,
                MemResident: memInfo.RSS,
                MemVirtual:  memInfo.VMS,
                MemSwap:     memInfo.Swap,
            }
            stateChan <- state
        }
    }
}

Dans le code ci-dessus, nous utilisons d'abord un timer pour vérifier l'état du processus spécifié toutes les cinq secondes. Pendant le processus de détection, nous obtenons le handle de processus du pid spécifié via la fonction process.NewProcess() et utilisons les fonctions fournies pour obtenir l'utilisation du processeur et de la mémoire. Stockez ces informations dans une structure définie ci-dessus et envoyez-les vers l'extérieur via stateChan.

3. Exemple complet de code de surveillance du processus Golang

Sur la base des idées et du code de mise en œuvre ci-dessus, nous pouvons écrire un exemple complet de code de surveillance du processus Golang. Le code complet est le suivant :

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/process"
    "log"
    "time"
)

type ProcessState struct {
    CpuPercent    float64
    MemResident   uint64
    MemVirtual    uint64
    MemSwap       uint64
}

func main() {
    targetProcessName := "myApp"
    targetPidList := make([]int32, 0)
    processes, err := process.Processes()
    if err != nil {
        log.Fatalf("failed to get all processes: %v", err)
    }
    for _, proc := range processes {
        name, err := proc.Name()
        if err != nil || name != targetProcessName {
            continue
        }
        pid := proc.Pid
        targetPidList = append(targetPidList, pid)
        log.Printf("find target process %s, pid = %d\n", name, pid)
    }
    stateChan := make(chan ProcessState)
    for _, pid := range targetPidList {
        go checkProcessState(pid, stateChan)
    }
    for {
        select {
        case state := <-stateChan:
            if state.CpuPercent > 100.0 || state.MemSwap > 0 || state.MemVirtual > 2*state.MemResident {
                log.Printf("process is not healthy: %+v\n", state)
            } else {
                log.Printf("process is healthy: %+v\n", state)
            }
        }
    }
}

func checkProcessState(targetPid int32, stateChan chan<- ProcessState) {
    ticker := time.NewTicker(5 * time.Second)
    for {
        select {
        case <-ticker.C:
            proc, err := process.NewProcess(targetPid)
            if err != nil {
                log.Printf("failed to get process %d: %v", targetPid, err)
                continue
            }
            cpuPercent, err := proc.CPUPercent()
            if err != nil {
                log.Printf("failed to get cpu percent for process %d: %v", targetPid, err)
                continue
            }
            memInfo, err := proc.MemoryInfo()
            if err != nil {
                log.Printf("failed to get memory info for process %d: %v", targetPid, err)
                continue
            }
            state := ProcessState{
                CpuPercent:  cpuPercent,
                MemResident: memInfo.RSS,
                MemVirtual:  memInfo.VMS,
                MemSwap:     memInfo.Swap,
            }
            stateChan <- state
        }
    }
}

Dans cet exemple, nous trouvons d'abord le processus que nous devons surveiller, et démarrons une goroutine pour chaque processus afin de détecter régulièrement son état. Le programme reçoit en permanence des messages d'état de goroutine de chan et détermine si le programme fonctionne normalement en fonction de l'état. Si une anomalie de processus est détectée, les invites correspondantes seront fournies via les journaux.

IV.Résumé

Cet article présente comment utiliser le langage Go pour implémenter la surveillance des processus, principalement en appelant l'API fournie dans le package psutil et en utilisant goroutine pour une détection régulière. La surveillance des processus nous permet de mieux contrôler l'état d'exécution de l'application et de gérer rapidement les exceptions lorsque le programme se produit, nous aidant ainsi à mieux mettre en œuvre le développement, l'exploitation et la maintenance du système.

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:
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