你可能聽說過很多壓力測試工具,比如Apache JMeter、Locust、Siege等等,但有沒有想過用Go語言自己寫一個簡單又強大的高併行HTTP壓力測試工具呢?Go語言的併發特性,特別是Goroutine的輕量級併發機制,讓它成為編寫高效壓力測試工具的絕佳選擇。今天,我們就來看看如何用Go寫一個自己的HTTP壓力測試工具,並瞭解Goroutine如何在超多I/O併行場景中大放異彩。
Go語言最強大的武器之一就是它的併發處理能力,特別是Goroutine。與傳統的Thread(線程)相比,Goroutine更加輕量,每個Goroutine僅佔用幾KB的記憶體,使我們可以輕鬆創建數千甚至數萬個Goroutine來處理高併發任務。這使得Go非常適合處理大量I/O操作,比如HTTP請求、網路通訊等。
go關鍵字即可創建一個新的Goroutine,沒有複雜的配置。我們的目標是創建一個簡單的HTTP壓力測試工具,它能夠:
接下來,我們來看看如何用Go實現這個工具:
package main
import (
    "fmt"
    "net/http"
    "sync"
    "time"
)
// 壓力測試參數
const (
    targetURL      = "http://example.com" // 測試目標URL
    totalRequests  = 1000                 // 總請求數
    concurrency    = 100                  // 併發數量
)
// 統計數據
var (
    successCount int
    failureCount int
    totalTime    time.Duration
    mutex        sync.Mutex
)
func main() {
    // 計時開始
    start := time.Now()
    // 使用WaitGroup等待所有請求完成
    var wg sync.WaitGroup
    requestChan := make(chan struct{}, concurrency) // 控制併發數量
    for i := 0; i < totalRequests; i++ {
        requestChan <- struct{}{} // 將請求加入併發控制管道
        wg.Add(1)
        go func() {
            defer wg.Done()
            sendRequest()
            <-requestChan // 完成請求後釋放chain
        }()
    }
    wg.Wait()
    elapsed := time.Since(start)
    // 輸出結果
    fmt.Printf("Total Requests: %d\n", totalRequests)
    fmt.Printf("Success Count: %d\n", successCount)
    fmt.Printf("Failure Count: %d\n", failureCount)
    fmt.Printf("Total Time: %v\n", elapsed)
    fmt.Printf("Average Time per Request: %v\n", totalTime/time.Duration(successCount+failureCount))
}
// 發送HTTP請求的函式
func sendRequest() {
    start := time.Now()
    resp, err := http.Get(targetURL)
    duration := time.Since(start)
    // 保護統計數據
    mutex.Lock()
    totalTime += duration
    if err != nil || resp.StatusCode != http.StatusOK {
        failureCount++
    } else {
        successCount++
    }
    mutex.Unlock()
}
sync.WaitGroup來等待所有的請求完成,並使用channel來控制併發數量,避免Goroutine數量過多導致記憶體不足。sync.Mutex來保護統計變數的安全,防止數據競爭。透過這個例子,我們可以看出Go語言在高併發場景中的優勢:
Go語言以其高效的併發模型,讓我們能輕鬆寫出高性能的HTTP壓力測試工具。無論是系統測試、API性能測試,還是日常開發,Go的輕量併發特性都能大大提高我們的開發效率。