在Golang中对HTTP服务做性能测试,核心目标是拿到两个指标:吞吐量(每秒处理请求数)和延迟(单次请求响应耗时)。我们可以不依赖第三方压测工具,直接用标准库写出可控的测试程序。

搭建被测HTTP服务
先用 net/http/httptest 启动一个本地测试服务,避免对外依赖。下面代码给出一个简单接口:
package main
import (
"net/http"
"net/http/httptest"
)
// 创建一个简单的HTTP服务用于测试
func startTestServer() *httptest.Server {
mux := http.NewServeMux()
mux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("pong"))
})
return httptest.NewServer(mux)
}
编写并发压测逻辑
使用 sync.WaitGroup 控制并发,用 time.Now() 记录每个请求耗时,最后汇总吞吐量和延迟。
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
func benchmark(serverURL string, totalReq int, concurrency int) {
var wg sync.WaitGroup
reqPerWorker := totalReq / concurrency
var totalLatency time.Duration
var mu sync.Mutex
start := time.Now()
for i := 0; i < concurrency; i++ {
wg.Add(1)
go func() {
defer wg.Done()
client := &http.Client{Timeout: 2 * time.Second}
for j := 0; j < reqPerWorker; j++ {
t := time.Now()
resp, err := client.Get(serverURL + "/ping")
if err == nil {
resp.Body.Close()
}
latency := time.Since(t)
mu.Lock()
totalLatency += latency
mu.Unlock()
}
}()
}
wg.Wait()
elapsed := time.Since(start)
fmt.Printf("总请求数: %dn", totalReq)
fmt.Printf("总耗时: %vn", elapsed)
fmt.Printf("吞吐量: %.2f req/sn", float64(totalReq)/elapsed.Seconds())
fmt.Printf("平均延迟: %vn", totalLatency/time.Duration(totalReq))
}
func main() {
srv := startTestServer()
defer srv.Close()
benchmark(srv.URL, 1000, 50)
}
理解结果指标
吞吐量等于总请求数除以总耗时,反映服务处理能力。延迟取所有请求耗时的平均值,若要更细可以记录最大延迟或分位数。表格列出常见关注点:
| 指标 | 含义 | 计算方式 |
|---|---|---|
| 吞吐量 | 单位时间处理请求数 | totalReq / elapsed.Seconds() |
| 平均延迟 | 单次请求平均耗时 | totalLatency / totalReq |
注意事项
- 压测客户端和服务端最好同机或低延迟网络,减少干扰。
- 并发数不要超过系统文件句柄限制。
- 多次运行取稳定值,避免冷启动影响。
用Golang写性能测试程序,逻辑透明且易于调整,是测量HTTP服务吞吐量和延迟的实用做法。