Golang并发发送HTTP请求的各种方法

admin 轻心小站 关注 LV.19 运营
发表于Go语言交流版块 教程

在Go语言中,并发发送HTTP请求是一种常见的场景,特别是在爬虫、API测试、负载测试等应用中。Go提供了多种方式来实现并发请求,以下是一些常用的方法:1. 使用goroutine和net/http包

在Go语言中,并发发送HTTP请求是一种常见的场景,特别是在爬虫、API测试、负载测试等应用中。Go提供了多种方式来实现并发请求,以下是一些常用的方法:

1. 使用goroutine和net/http包

你可以为每个请求创建一个goroutine,并使用net/http包中的http.Client来发送请求。

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    URLs := []string{
        "http://example.com",
        "http://example.org",
        "http://example.net",
    }

    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
            }
            body, err := ioutil.ReadAll(resp.Body)
            resp.Body.Close()
            if err != nil {
                fmt.Println(err)
                return
            }
            fmt.Println(url, string(body))
        }(url)
    }

    wg.Wait()
}

2. 使用sync.WaitGroup等待所有请求完成

sync.WaitGroup是一个计数器,可以用来等待所有goroutine完成。

var wg sync.WaitGroup
wg.Add(len(URLs))
for _, url := range URLs {
    go func(url string) {
        defer wg.Done()
        // 发送请求并处理
    }()
}
wg.Wait()

3. 使用context包进行超时和取消操作

context包可以用来在goroutine之间传递请求的截止时间或取消信号。

ctx, cancel := context.WithTimeout(context.Background(), time.Second * 10)
defer cancel()

resp, err := http.Get(url)
if err != nil {
    if ctx.Err() == context.DeadlineExceeded {
        fmt.Println("Request timeout")
    } else {
        fmt.Println("Request error", err)
    }
    return
}
// 处理响应

4. 使用pool模式重用HTTP客户端

创建一个HTTP客户端池,可以减少创建和销毁客户端的开销。

type ClientPool struct {
    pool *sync.Pool
}

func NewClientPool() *ClientPool {
    return &ClientPool{
        pool: &sync.Pool{
            New: func() interface{} {
                return &http.Client{
                    Timeout: time.Second * 10,
                }
            },
        },
    }
}

func (p *ClientPool) GetClient() *http.Client {
    return p.pool.Get().(*http.Client)
}

func (p *ClientPool) PutClient(client *http.Client) {
    p.pool.Put(client)
}

5. 使用第三方库

有许多第三方库提供了并发请求的功能,例如gorequest。

package main

import (
    "fmt"
    "gorequest"
)

func main() {
    resp, body, errs := gorequest.New().Get("http://example.com").
        SetDebug(true).
       ToEnd()

    if len(errs) > 0 {
        fmt.Println(errs)
    }
    fmt.Println(resp.Status)
    fmt.Println(string(body))
}

6. 使用golang.org/x/net/context包

这个包提供了WithDeadline和WithCancel等方法,可以用来控制请求的生命周期。

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // 创建请求
    req, err := http.NewRequest("GET", "http://example.com", nil)
    if err != nil {
        log.Fatal(err)
    }
    // 设置超时
    var cancel context.CancelFunc
    ctx, cancel = context.WithTimeout(ctx, 10*time.Second)
    defer cancel()

    // 发送请求
    client := &http.Client{}
    resp, err := client.Do(req.WithContext(ctx))
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    // 处理响应
}

总结

以上是在Go语言中并发发送HTTP请求的一些常用方法。你可以根据具体的需求和场景选择合适的方法。无论是使用标准库还是第三方库,都需要注意合理管理并发和资源,避免创建过多的goroutine或占用过多的资源。同时,正确处理错误和超时,确保程序的稳定性和可靠性。

文章说明:

本文原创发布于探乎站长论坛,未经许可,禁止转载。

题图来自Unsplash,基于CC0协议

该文观点仅代表作者本人,探乎站长论坛平台仅提供信息存储空间服务。

评论列表 评论
发布评论

评论: Golang并发发送HTTP请求的各种方法

粉丝

0

关注

0

收藏

0

已有0次打赏