在Go语言中,并发发送HTTP请求是一种常见的场景,特别是在爬虫、API测试、负载测试等应用中。Go提供了多种方式来实现并发请求,以下是一些常用的方法:1. 使用goroutine和net/http包
在Go语言中,并发发送HTTP请求是一种常见的场景,特别是在爬虫、API测试、负载测试等应用中。Go提供了多种方式来实现并发请求,以下是一些常用的方法:
你可以为每个请求创建一个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()
}
sync.WaitGroup是一个计数器,可以用来等待所有goroutine完成。
var wg sync.WaitGroup
wg.Add(len(URLs))
for _, url := range URLs {
go func(url string) {
defer wg.Done()
// 发送请求并处理
}()
}
wg.Wait()
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
}
// 处理响应
创建一个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)
}
有许多第三方库提供了并发请求的功能,例如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))
}
这个包提供了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或占用过多的资源。同时,正确处理错误和超时,确保程序的稳定性和可靠性。
暂无管理员
粉丝
0
关注
0
收藏
0