lolly/internal/middleware/security/ratelimit_bench_test.go
xfy f145a8770e refactor: modernize code with Go 1.22+ features
Apply modern Go patterns across the codebase:
- Replace `interface{}` with `any` (Go 1.18+)
- Use `for range n` instead of `for i := 0; i < n; i++` (Go 1.22+)
- Replace `sort.Slice` with `slices.Sort` from slices package
- Simplify sync.WaitGroup patterns with errgroup where appropriate
- Add Makefile targets for modernize analyzer

Total: 84 files updated, net reduction of 79 lines

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 10:37:45 +08:00

229 lines
5.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package security 提供限流中间件的基准测试。
//
// 该文件测试令牌桶限流器的性能,包括单客户端和多客户端场景。
//
// 作者xfy
package security
import (
"net"
"testing"
"github.com/valyala/fasthttp"
"rua.plus/lolly/internal/config"
)
// setupRateLimitRequestCtx 创建用于基准测试的 fasthttp.RequestCtx。
func setupRateLimitRequestCtx(ip string) *fasthttp.RequestCtx {
ctx := &fasthttp.RequestCtx{}
ctx.Request.Header.SetMethod(fasthttp.MethodGet)
ctx.Request.SetRequestURI("/api/test")
ctx.Init(&fasthttp.Request{}, &net.TCPAddr{
IP: net.ParseIP(ip),
Port: 12345,
}, nil)
return ctx
}
// BenchmarkRateLimiterAllow 测试单客户端 Allow 性能。
func BenchmarkRateLimiterAllow(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 1000,
Burst: 2000,
Key: "ip",
}
rl, _ := NewRateLimiter(cfg)
defer rl.(*RateLimiter).StopCleanup()
b.ResetTimer()
for b.Loop() {
rl.(*RateLimiter).Allow("192.168.1.100")
}
}
// BenchmarkRateLimiterAllowParallel_10Clients 测试 10 客户端并发 Allow 性能。
func BenchmarkRateLimiterAllowParallel_10Clients(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 10000,
Burst: 20000,
Key: "ip",
}
rl, _ := NewRateLimiter(cfg)
defer rl.(*RateLimiter).StopCleanup()
clients := make([]string, 10)
for i := range clients {
clients[i] = "192.168.1." + string(rune('0'+i))
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
rl.(*RateLimiter).Allow(clients[i%10])
i++
}
})
}
// BenchmarkRateLimiterAllowParallel_100Clients 测试 100 客户端并发 Allow 性能。
func BenchmarkRateLimiterAllowParallel_100Clients(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 100000,
Burst: 200000,
Key: "ip",
}
rl, _ := NewRateLimiter(cfg)
defer rl.(*RateLimiter).StopCleanup()
clients := make([]string, 100)
for i := range clients {
clients[i] = "10.0.0." + string(rune(i))
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
rl.(*RateLimiter).Allow(clients[i%100])
i++
}
})
}
// BenchmarkRateLimiterAllowParallel_1000Clients 测试 1000 客户端并发 Allow 性能。
func BenchmarkRateLimiterAllowParallel_1000Clients(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 1000000,
Burst: 2000000,
Key: "ip",
}
rl, _ := NewRateLimiter(cfg)
defer rl.(*RateLimiter).StopCleanup()
clients := make([]string, 1000)
for i := range clients {
clients[i] = "172.16.0." + string(rune(i%256))
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
rl.(*RateLimiter).Allow(clients[i%1000])
i++
}
})
}
// BenchmarkRateLimiterCleanup_1000Buckets 测试清理 1000 个过期桶的性能。
func BenchmarkRateLimiterCleanup_1000Buckets(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 100,
Burst: 200,
Key: "ip",
}
mw, _ := NewRateLimiter(cfg)
rl := mw.(*RateLimiter)
defer rl.StopCleanup()
// 预创建 1000 个桶
for i := range 1000 {
rl.Allow("192.168.0." + string(rune(i)))
}
b.ResetTimer()
for b.Loop() {
rl.Cleanup(0) // 清理所有桶
// 重新创建桶以保持测试一致性
for j := range 1000 {
rl.Allow("192.168.0." + string(rune(j)))
}
}
}
// BenchmarkKeyByIP 测试 IP 提取性能。
func BenchmarkKeyByIP(b *testing.B) {
ctx := setupRateLimitRequestCtx("192.168.1.100")
b.ResetTimer()
for b.Loop() {
keyByIP(ctx)
}
}
// BenchmarkRateLimiterMiddleware 组件级测试:测量限流中间件本身的开销。
func BenchmarkRateLimiterMiddleware(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 100000,
Burst: 200000,
Key: "ip",
}
rl, _ := NewRateLimiter(cfg)
defer rl.(*RateLimiter).StopCleanup()
mockHandler := func(ctx *fasthttp.RequestCtx) {
ctx.SetStatusCode(fasthttp.StatusOK)
ctx.SetBodyString("OK")
}
handler := rl.Process(mockHandler)
b.ResetTimer()
for b.Loop() {
ctx := setupRateLimitRequestCtx("192.168.1.100")
handler(ctx)
}
}
// BenchmarkRateLimiterMiddlewareParallel 测试并发场景下的中间件性能。
func BenchmarkRateLimiterMiddlewareParallel(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 1000000,
Burst: 2000000,
Key: "ip",
}
rl, _ := NewRateLimiter(cfg)
defer rl.(*RateLimiter).StopCleanup()
mockHandler := func(ctx *fasthttp.RequestCtx) {
ctx.SetStatusCode(fasthttp.StatusOK)
ctx.SetBodyString("OK")
}
handler := rl.Process(mockHandler)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
ip := "192.168.1." + string(rune('0'+i%10))
ctx := setupRateLimitRequestCtx(ip)
handler(ctx)
i++
}
})
}
// BenchmarkRateLimiterStats 测试获取统计信息的性能。
func BenchmarkRateLimiterStats(b *testing.B) {
cfg := &config.RateLimitConfig{
RequestRate: 1000,
Burst: 2000,
Key: "ip",
}
mw, _ := NewRateLimiter(cfg)
rl := mw.(*RateLimiter)
defer rl.StopCleanup()
// 预创建一些桶
for i := range 100 {
rl.Allow("192.168.0." + string(rune(i)))
}
b.ResetTimer()
for b.Loop() {
rl.GetStats()
}
}