如何限制http.HandleFunc并发数量?

leenzhu · · 4243 次点击
<a href="/user/leenzhu" title="@leenzhu">@leenzhu</a> 确实。实际上即使起了 goroutine 调用 handle 了,也直接返回了,开销很小,所以不太懂为啥要限制这个呀。
#5
更多评论
``` package main import ( &#34;fmt&#34; &#34;net/http&#34; &#34;net/http/httptest&#34; &#34;time&#34; &#34;golang.org/x/time/rate&#34; ) type LimiterOption struct { lm *rate.Limiter } func WithLimiter(duration time.Duration, count int) func(o *LimiterOption) { return func(o *LimiterOption) { o.lm = rate.NewLimiter(rate.Every(duration), count) } } // LimiterWrap 每个 handler 单独限制 func LimiterWrap(f http.HandlerFunc, opts ...func(o *LimiterOption)) http.HandlerFunc { o := &amp;LimiterOption{ lm: rate.NewLimiter(rate.Every(100*time.Millisecond), 10), } for _, opt := range opts { opt(o) } return func(w http.ResponseWriter, r *http.Request) { if !o.lm.Allow() { w.WriteHeader(http.StatusInternalServerError) return } f(w, r) } } func xHandle(w http.ResponseWriter, r *http.Request) { w.Write([]byte(&#34;Hello\n&#34;)) } func main() { // 单独控制一个接口 http.HandleFunc(&#34;/&#34;, LimiterWrap(xHandle, WithLimiter(100*time.Millisecond, 1))) // 所有接口都走同一个限流 // http.ListenAndServe(&#34;:8080&#34;, LimiterWrap(http.DefaultServeMux.ServeHTTP)) for i := 0; i &lt; 10; i++ { w := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodGet, &#34;/&#34;, nil) http.DefaultServeMux.ServeHTTP(w, req) fmt.Println(i, w.Code) time.Sleep(time.Millisecond * 20) } //output //0 200 //1 500 //2 500 //3 500 //4 500 //5 200 //6 500 //7 500 //8 500 //9 500 } ```
#1
```go package main func success() {} func fail() {} func main() { c := make(chan struct{}, 16) select { case c &lt;- struct{}{}: success() &lt;-c default: fail() } } ```
#2