golang自身的net/http網(wǎng)絡(luò)接口也很方便,但是復(fù)雜的業(yè)務(wù)就沒有開源框架來的順手,比如gin微服務(wù)框架
限流用在業(yè)務(wù)較多的服務(wù)中钞诡,每秒允許多少請求,延遲最長多少湃崩,允許同時(shí)多少IP在線等荧降。
1,net/http攒读,簡單監(jiān)聽一下本地3050端口朵诫,限制只能允許一個IP接入,max=1
func main() {
l, err := net.Listen("tcp", "192.168.100.8:3050")
if err != nil {
fmt.Println("list err")
}
defer l.Close()
const max = 1
l = netutil.LimitListener(l, 1)
var open int32
http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if n := atomic.AddInt32(&open, 1); n > max {
fmt.Println("connetct",n,max)
}
defer atomic.AddInt32(&open, -1)
time.Sleep(10 * time.Millisecond)
fmt.Fprint(w, "some body")
}))
}
接入成功的客戶端顯示:
以后接入的客戶端顯示:
無法請求到服務(wù)器
如果max值改大一點(diǎn)薄扁,那么更多客戶端就可以連接到服務(wù)器剪返。
2,gin-limiter泌辫,gin作為最近golang最流行的服務(wù)框架之一随夸,使用起來也非常方便engine := gin.default(),可以使用各種中間件配置震放,測試限流效果和net/http一致,安裝"github.com/didip/tollbooth"略
func LimitHandler(lmt *limiter.Limiter) gin.HandlerFunc {
return func(c *gin.Context) {
httpError := tollbooth.LimitByRequest(lmt, c.Writer, c.Request)
if httpError != nil {
c.Data(httpError.StatusCode, lmt.GetMessageContentType(), []byte(httpError.Message))
c.Abort()
} else {
c.Next()
}
}
}
lmt := tollbooth.NewLimiter(max,nil)
lmt.SetMessage("error驼修,殿遂,")
engine.POST("/login",tollbooth.LimitHandler(lmt,nil),LoginHandler)