如何限制Go API的并发连接

时间:2019-09-16 20:59:35

标签: go

我正在使用listenandserve启动Go API以接受HTTP请求。

我如何实现以下目标?

  1. 最多允许100个并发HTTP请求
  2. 第101个请求(以及其他任何请求)应等待10分钟才能尝试达到此“ 100个并发”限制(即希望前100个请求中的一些请求应会完成)
  3. 如果经过10分钟,并且没有打开可用的请求“插槽”,则对于一直等待的请求返回错误
  4. 接下来要执行的请求101 ... 102 ... x的顺序不重要

当前版本完全不可用:

    timeout := time.After(10 * time.Minute)
    tick := time.Tick(15 * time.Second)
    fullcmdfirst := fmt.Sprintf("netstat -anp | grep procname | grep ESTABLISHED | grep -v grep | wc -l")
    outputfirst, err1first := exec.Command("/bin/sh", "-c", fullcmdfirst).CombinedOutput()
    if strconv.ParseFloat(string(outputfirst)) < 100 {
        return nil
    }

    // Keep trying until we're timed out or lock acquired
    for {
        select {
        // Got a timeout! fail with a timeout error
        case <-timeout:
            return errors.New("Error: timed out ")
        // Got a tick, we should check if we can acquire
        case <-tick:
            fullcmd := fmt.Sprintf("netstat -anp | grep procname | grep ESTABLISHED | grep -v grep | wc -l")
            output, err1 := exec.Command("/bin/sh", "-c", fullcmd).CombinedOutput()
            if strconv.ParseFloat(string(outputfirst)) < 100 {
                l.Printf("start req")
                return nil
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

不需要netstats或代码或其他任何东西(无论如何都行不通-一旦netstat看到<100个连接,任何通知都不会阻止接下来的100个请求,并且您最终在以下位置运行199个请求一次;此外,等待处理的请求仍将在netstat中出现-限制连接完全是另一个问题)。只需将缓冲的通道用作信号灯即可;它已经是线程安全的。

sem := make(chan struct{}, 100)

func myHandler(w http.ResponseWriter, r *http.Request) {
    timeout := time.After(10 * time.Minute)
    select {
        case <- timeout:
            http.Error(w, "Sorry", http.StatusUnavailable)
            return
        case sem <- struct{}:
            w.Write([]byte("Hello"))
            <- sem
            return
    }
}

请注意,尽管大多数客户早在10分钟标记之前就已经超时。

相关问题