package main
import (
"fmt"
"net/http"
"sync"
"sync/atomic"
"time"
)
// 并发发送HTTP请求的示例
func main() {
var (
wg sync.WaitGroup
successful uint32 // 原子操作计数器
failures uint32
rateLimiter = time.NewTicker(time.Millisecond * 100) // 速率限制器,每100毫秒发送一个请求
)
// 假设有一个URL列表
urls := []string{
"http://example.com/1",
"http://example.com/2",
// ... 更多URL
}
// 为每个URL设置goroutine
for _, url := range urls {
wg.Add(1)
go func(url string) {
defer wg.Done()
<-rateLimiter.C // 等待速率限制器发送信号
if err := sendRequest(url); err == nil {
atomic.AddUint32(&successful, 1)
} else {
atomic.AddUint32(&failures, 1)
}
}(url)
}
// 等待所有请求完成
wg.Wait()
rateLimiter.Stop() // 停止速率限制器
fmt.Printf("Successful: %d, Failures: %d\n", successful, failures)
}
// 发送HTTP GET请求
func sendRequest(url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return nil
}
这段代码使用了sync.WaitGroup
来等待所有的goroutines完成,使用了sync/atomic
包中的函数来原子地增加成功和失败的请求计数,使用了time.Ticker
来限制请求的发送速率。这是一个简化的示例,展示了如何在Golang中并发地发送HTTP请求,并通过速率限制和错误处理来提高程序的健壮性。