golang自身的net/http网络接口也很方便,但是复杂的业务就没有开源框架来的顺手,比如gin微服务框架
限流用在业务较多的服务中,每秒允许多少请求,延迟最长多少,允许同时多少IP在线等。
1,net/http,简单监听一下本地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")
}))
}
接入成功的客户端显示:
以后接入的客户端显示:
无法请求到服务器
如果max值改大一点,那么更多客户端就可以连接到服务器。
2,gin-limiter,gin作为最近golang最流行的服务框架之一,使用起来也非常方便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)