Golang 中简单的并发限制与超时控制

2019-06-25  本文已影响0人  hwholiday

代码地址 点击这里

并发限制(一种常见的做法就是利用 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

上一篇下一篇

猜你喜欢

热点阅读