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")
    }))
}
接入成功的客户端显示:

image.png
以后接入的客户端显示:

image.png
无法请求到服务器
如果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)