Maison  >  Article  >  développement back-end  >  requêtes simultanées Golang

requêtes simultanées Golang

王林
王林original
2023-05-19 16:02:41605parcourir

Dans les applications Web modernes, les requêtes réseau jouent un rôle crucial. Avec les requêtes réseau, nous pouvons facilement obtenir et envoyer des données. Cependant, à mesure que la taille des demandes continue d’augmenter, le nombre de demandes augmentera également. Dans ce cas, la manière d’assurer la stabilité et l’efficacité du système devient particulièrement importante.

Le langage Go est un langage de programmation simultanée efficace avec une bonne gestion de la mémoire et un bon contrôle de la concurrence, il est donc excellent pour gérer un nombre élevé de requêtes simultanées. Cet article explique comment utiliser le langage Go pour gérer les requêtes simultanées.

  1. Traitement simultané des requêtes

De manière générale, une requête réseau se compose de trois étapes : l'établissement d'une connexion, l'envoi d'une requête et la réception d'une réponse. Dans une application traditionnelle, chaque requête passe par ces trois étapes. Cependant, dans les applications à forte concurrence, cette approche est inefficace car chaque requête doit attendre la fin de la requête précédente avant de pouvoir commencer son exécution.

Voici une approche différente. Nous pouvons utiliser la fonctionnalité de concurrence du langage Go pour exécuter plusieurs requêtes en même temps, afin que l'application puisse gérer plusieurs requêtes en même temps.

Voici un exemple de code simple :

func main() {
    urls := []string{
        "http://example.com",
        "http://example.net",
        "http://example.org",
    }

    ch := make(chan string)

    for _, url := range urls {
        go fetch(url, ch)
    }

    for range urls {
        fmt.Println(<-ch)
    }
}

func fetch(url string, ch chan<- string) {
    resp, err := http.Get(url)
    if err != nil {
        ch <- fmt.Sprint(err)
        return
    }
    defer resp.Body.Close()

    text, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        ch <- fmt.Sprint(err)
        return
    }

    ch <- fmt.Sprintf("url:%s, body:%s", url, text[:100])
}

Dans cet exemple, nous définissons une tranche qui contient plusieurs URL. Nous avons ensuite créé un canal tamponné et utilisé le mot-clé go pour démarrer une goroutine afin de gérer chaque requête simultanément. Dans la goroutine, nous effectuons les mêmes étapes que pour traiter une seule requête et utilisons un canal pour renvoyer le résultat au programme principal. Enfin, nous utilisons une simple boucle for range pour attendre que toutes les requêtes soient terminées et imprimer les résultats. go关键字来启动一个goroutine,同时处理每个请求。在goroutine中,我们执行与处理单个请求相同的步骤,并使用通道来将结果发送回主程序。最后,我们使用一个简单的for range循环来等待所有请求完成并打印结果。

  1. 控制并发量

在上面的示例中,我们使用了goroutine来并发处理多个请求。但是这样做可能导致系统被过多的请求阻塞而崩溃。为了避免这种情况,我们需要控制并发量。

在Go语言中,sync包中的WaitGroup结构可以很好地解决这个问题。这个结构允许我们在代码块中增加并发数量,并等待所有任务完成后再继续执行。下面是一个简单的示例代码:

func main() {
    urls := []string{
        "http://example.com",
        "http://example.net",
        "http://example.org",
    }

    var wg sync.WaitGroup

    for _, url := range urls {
        wg.Add(1)
        go func(url string) {
            defer wg.Done()

            resp, err := http.Get(url)
            if err != nil {
                fmt.Println(err)
                return
            }
            defer resp.Body.Close()

            body, err := ioutil.ReadAll(resp.Body)
            if err != nil {
                fmt.Println(err)
                return
            }

            fmt.Printf("url:%s, body:%s", url, body[:20])
        }(url)
    }

    wg.Wait()
}

在这个示例中,我们首先定义一个WaitGroup变量。在循环中,我们使用Add方法增加并发数量计数。然后,我们启动一个goroutine来处理每个请求。最后,我们使用Wait方法来等待所有goroutine完成并恢复执行。

  1. 并发地处理请求结果

在处理多个请求时,我们不仅需要控制并发量,还需要处理并发结果。一般而言,我们需要把所有请求的结果收集到一个数组或其他数据结构中,并在所有请求完成后进行处理。

Go语言中,我们可以使用sync包中的Mutex结构组织多个goroutine对数据结构的访问。Mutex可以防止多个goroutine同时修改共享资源,并确保同一时间只有一个goroutine可以访问。

下面是一个示例代码:

type Result struct {
    url string
    body []byte
    err error
}

func fetch(url string, ch chan<- Result) {
    resp, err := http.Get(url)
    if err != nil {
        ch <- Result{url: url, err: err}
        return
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        ch <- Result{url: url, err: err}
        return
    }

    ch <- Result{url: url, body: body}
}
func main() {
    urls := []string{
        "http://example.com",
        "http://example.net",
        "http://example.org",
    }

    var results []Result
    ch := make(chan Result)

    for _, url := range urls {
        go fetch(url, ch)
    }

    for range urls {
        results = append(results, <-ch)
    }

    for _, result := range results {
        if result.err != nil {
            fmt.Println(result.err)
            continue
        }
        fmt.Printf("url:%s, body:%s", result.url, result.body[:20])
    }
}

在这个示例中,我们定义了一个Result结构来保存每个请求的返回值。然后,我们创建了一个缓冲通道,并使用goroutine并发执行每个请求。在goroutine中,我们使用Mutex来确保共享资源不会被多个goroutine同时访问。最后,我们使用一个循环等待所有请求完成,并收集结果到一个数组中。最后,我们遍历结果数组并打印每个请求的返回值。

总结

使用Go语言处理并发请求可以大大提高系统的效率和可靠性。在应用程序需要处理大量请求时,我们应该使用goroutine和通道来并发执行请求,并使用WaitGroupMutex

    Contrôlez le degré de concurrence🎜🎜🎜Dans l'exemple ci-dessus, nous avons utilisé goroutine pour gérer plusieurs requêtes simultanément. Cependant, cela pourrait entraîner le blocage du système par un trop grand nombre de requêtes et un crash. Pour éviter cette situation, nous devons contrôler le degré de concurrence. 🎜🎜En langage Go, la structure WaitGroup du package sync peut très bien résoudre ce problème. Cette structure nous permet d'augmenter le degré de concurrence dans un bloc de code et d'attendre que toutes les tâches soient terminées avant de continuer. Voici un exemple de code simple : 🎜rrreee🎜 Dans cet exemple, nous définissons d'abord une variable WaitGroup. Dans la boucle, nous utilisons la méthode Add pour augmenter le nombre de concurrences. Ensuite, nous démarrons une goroutine pour gérer chaque requête. Enfin, nous utilisons la méthode Wait pour attendre que toutes les goroutines se terminent et reprennent l'exécution. 🎜
      🎜Traitement simultané des résultats des demandes🎜🎜🎜Lors du traitement de plusieurs demandes, nous devons non seulement contrôler le degré de simultanéité, mais également gérer les résultats simultanés. De manière générale, nous devons collecter les résultats de toutes les requêtes dans un tableau ou une autre structure de données et les traiter une fois toutes les requêtes terminées. 🎜🎜En langage Go, nous pouvons utiliser la structure Mutex dans le package sync pour organiser l'accès de plusieurs goroutines aux structures de données. Mutex peut empêcher plusieurs goroutines de modifier les ressources partagées en même temps et garantir qu'une seule goroutine peut y accéder en même temps. 🎜🎜Voici un exemple de code : 🎜rrreee🎜Dans cet exemple, nous définissons une structure Result pour enregistrer la valeur de retour de chaque requête. Nous avons ensuite créé un canal tamponné et utilisé une goroutine pour exécuter chaque requête simultanément. Dans goroutine, nous utilisons Mutex pour garantir que les ressources partagées ne sont pas accessibles par plusieurs goroutines en même temps. Enfin, nous utilisons une boucle pour attendre que toutes les requêtes soient terminées et collecter les résultats dans un tableau. Enfin, nous parcourons le tableau des résultats et imprimons la valeur de retour de chaque requête. 🎜🎜Résumé🎜🎜L'utilisation du langage Go pour gérer les requêtes simultanées peut considérablement améliorer l'efficacité et la fiabilité du système. Lorsque l'application doit gérer un grand nombre de requêtes, nous devons utiliser des goroutines et des canaux pour exécuter les requêtes simultanément, et utiliser WaitGroup et Mutex pour contrôler le degré de concurrence et protéger ressources partagées. De cette manière, nous pouvons traiter un grand nombre de requêtes de manière simple et efficace, améliorant ainsi les performances et la stabilité des applications. 🎜

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
Article précédent:paramètres du chemin GolangArticle suivant:paramètres du chemin Golang