调整工具类的方法,优化方法调用及增加迁移工具及其用法
This commit is contained in:
89
examples/middleware_ratelimit_example.go
Normal file
89
examples/middleware_ratelimit_example.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
commonhttp "git.toowon.com/jimmy/go-common/http"
|
||||
"git.toowon.com/jimmy/go-common/middleware"
|
||||
)
|
||||
|
||||
// 示例:限流中间件的使用
|
||||
// 展示不同的限流策略
|
||||
func main() {
|
||||
// 策略1:按IP限流(10请求/分钟)
|
||||
ipLimitChain := middleware.NewChain(
|
||||
middleware.RateLimitByIP(10, time.Minute),
|
||||
)
|
||||
|
||||
// 策略2:按用户ID限流(100请求/分钟)
|
||||
limiter := middleware.NewTokenBucketLimiter(100, time.Minute)
|
||||
userLimitConfig := &middleware.RateLimitConfig{
|
||||
Limiter: limiter,
|
||||
KeyFunc: func(r *http.Request) string {
|
||||
// 从请求头获取用户ID
|
||||
userID := r.Header.Get("X-User-ID")
|
||||
if userID != "" {
|
||||
return "user:" + userID
|
||||
}
|
||||
// 没有用户ID则使用IP
|
||||
return "ip:" + r.RemoteAddr
|
||||
},
|
||||
OnRateLimitExceeded: func(w http.ResponseWriter, r *http.Request, key string) {
|
||||
log.Printf("Rate limit exceeded for key: %s, path: %s", key, r.URL.Path)
|
||||
},
|
||||
}
|
||||
userLimitChain := middleware.NewChain(
|
||||
middleware.RateLimit(userLimitConfig),
|
||||
)
|
||||
|
||||
// 路由1:按IP限流的API(严格限制)
|
||||
http.Handle("/api/public", ipLimitChain.ThenFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
h := commonhttp.NewHandler(w, r)
|
||||
h.Success(map[string]interface{}{
|
||||
"message": "Public API - IP rate limited (10/min)",
|
||||
"tip": "Try refreshing quickly to see rate limiting",
|
||||
})
|
||||
}))
|
||||
|
||||
// 路由2:按用户ID限流的API(宽松限制)
|
||||
http.Handle("/api/private", userLimitChain.ThenFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
h := commonhttp.NewHandler(w, r)
|
||||
userID := r.Header.Get("X-User-ID")
|
||||
if userID == "" {
|
||||
h.Error(401, "Missing X-User-ID header")
|
||||
return
|
||||
}
|
||||
h.Success(map[string]interface{}{
|
||||
"message": "Private API - User rate limited (100/min)",
|
||||
"user_id": userID,
|
||||
})
|
||||
}))
|
||||
|
||||
// 路由3:无限流的API(用于测试对比)
|
||||
http.HandleFunc("/api/unlimited", func(w http.ResponseWriter, r *http.Request) {
|
||||
h := commonhttp.NewHandler(w, r)
|
||||
h.Success(map[string]interface{}{
|
||||
"message": "Unlimited API - No rate limiting",
|
||||
})
|
||||
})
|
||||
|
||||
// 启动服务器
|
||||
addr := ":8080"
|
||||
log.Printf("Server starting on %s", addr)
|
||||
log.Println("Test endpoints:")
|
||||
log.Printf(" - IP limited (10/min): http://localhost%s/api/public", addr)
|
||||
log.Printf(" - User limited (100/min): http://localhost%s/api/private (add X-User-ID header)", addr)
|
||||
log.Printf(" - No limit: http://localhost%s/api/unlimited", addr)
|
||||
log.Println("\nTest with curl:")
|
||||
log.Printf(" curl http://localhost%s/api/public", addr)
|
||||
log.Printf(" curl -H 'X-User-ID: user123' http://localhost%s/api/private", addr)
|
||||
log.Println("\nResponse headers:")
|
||||
log.Println(" X-RateLimit-Limit: Total allowed requests")
|
||||
log.Println(" X-RateLimit-Remaining: Remaining requests")
|
||||
log.Println(" X-RateLimit-Reset: Reset timestamp")
|
||||
|
||||
log.Fatal(http.ListenAndServe(addr, nil))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user