Vegeta をライブラリとして利用することで、Goで負荷試験シナリオを柔軟に作ることもできる。 公式ドキュメント https://github.com/tsenart/vegeta#usage-library サンプル package main import ( "fmt" "net/http" "sync/atomic" "time" vegeta "github.com/tsenart/vegeta/v12/lib" ) func main() { // 負荷試験パラメータ(例: 1秒間に5リクエストを100秒間実行する) rate := vegeta.Rate{Freq: 5, Per: time.Second} duration := 100 * time.Second targets := make([]vegeta.Target, 0) // リクエストを作る targets = append(targets, vegeta.Target{ Method: "GET", URL: "https://example.com/get", }) targets = append(targets, vegeta.Target{ Method: "POST", URL: "https://example.com/post", Body: []byte(`{"name": "Corey", "animal": "dog"}`), Header: http.Header{ "Content-Type": []string{"application/json"}, }, }) targeter := vegeta.NewStaticTargeter(targets...) attacker := vegeta.NewAttacker() var metrics vegeta.Metrics for res := range attacker.Attack(targeter, rate, duration, "Big Bang!") { metrics.Add(res) } metrics.Close() fmt.Printf("result: %+v\n", metrics) } 複雑な例 負荷リクエストのパラメータを可変にしたい場合次のように書ける。 package main import ( "fmt" "net/url" "sync/atomic" "time" vegeta "github.com/tsenart/vegeta/v12/lib" ) func main() { // 負荷試験パラメータ(例: 1秒間に5リクエストを100秒間実行する) rate := vegeta.Rate{Freq: 5, Per: time.Second} duration := 100 * time.Second targets := make([]vegeta.Target, 0) // リクエストを作る targets = append(targets, vegeta.Target{ Method: "GET", URL: "https://example.com/get?id=00000000", }) // 自作したTargeterを利用する targeter := NewCustomTargeter(targets...) attacker := vegeta.NewAttacker() var metrics vegeta.Metrics for res := range attacker.Attack(targeter, rate, duration, "Big Bang!") { metrics.Add(res) } metrics.Close() fmt.Printf("result: %+v\n", metrics) } // NewCustomTargeter targetを作る処理を自作する func NewCustomTargeter(tgts ...vegeta.Target) vegeta.Targeter { i := int64(-1) loopCount := 0 return func(tgt *vegeta.Target) error { if tgt == nil { return vegeta.ErrNilTarget } addedIndex := atomic.AddInt64(&i, 1) *tgt = tgts[addedIndex%int64(len(tgts))] // 1周したらloopCountを増やす if addedIndex%int64(len(tgts)) == 0 { loopCount++ } u, _ := url.Parse(tgt.URL) q := u.Query() q.Set("id", fmt.Sprintf("%08d", loopCount)) u.RawQuery = q.Encode() tgt.URL = u.String() return nil } }