并发限制(一种常见的做法就是利用 channel 的缓冲机制)
var limitChan = make(chan bool, n)
如果 channel 没有缓冲,或者缓冲区满了。goroutine 会自动阻塞,直到 channel 里的数据被读走为止
代码演示
var addr = flag.String("p", "192.168.2.28:8099", "port")
func main() {
flag.Parse()
perf.StartPprof([]string{"192.168.2.28:9022"})
logtool.InitZapLogger("ghost.log", true)
//http服务
mux := http.NewServeMux()
mux.HandleFunc("/limit_api", limitApi)
s := &http.Server{
Handler: mux,
Addr: *addr,
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
MaxHeaderBytes: 1 << 20,
}
go func() {
err := s.ListenAndServe()
if err != nil {
logtool.Zap.Panic("bat_file err", zap.Error(err))
}
}()
quit.QuitSignal(func() {
s.Close()
fmt.Println("退出程序")
})
}
var limitChan = make(chan bool, 1) //每次执行一个请求
func limitApi(w http.ResponseWriter, r *http.Request) {
select {
case limitChan <- true:
case <-time.After(2 * time.Second): //2秒不能写入服务器返回错误
fmt.Println("服务器限流")
w.Write([]byte("ERR"))
return
}
//延迟释放limitChan 模拟超时
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Intn(4)) * time.Second)
<-limitChan
fmt.Println("服务器正常访问")
w.Write([]byte("OK"))
return
}
控制台输出
server start success pid:19309
服务器限流
服务器正常访问
服务器正常访问
服务器限流
服务器正常访问
服务器正常访问
服务器正常访问
退出程序
联系 QQ: 3355168235
网友评论