如何限制Go API的并发连接

如何限制Go API的并发连接,go,Go,我正在启动一个带有ListendServe的GoAPI来接受HTTP请求 我怎样才能达到以下目标 允许最多100个同时HTTP请求 第101个请求(以及任何其他请求)应等待10分钟,以尝试落入此“100同时”限制(即希望前100个请求中的某些请求能够完成) 如果10分钟过去了,但没有打开可用的请求“插槽”,则为等待的请求返回错误 接下来运行的请求101…102…x的顺序并不重要 当前版本完全取消: timeout := time.After(10 * time.Minute) t

我正在启动一个带有ListendServe的GoAPI来接受HTTP请求

我怎样才能达到以下目标

  • 允许最多100个同时HTTP请求
  • 第101个请求(以及任何其他请求)应等待10分钟,以尝试落入此“100同时”限制(即希望前100个请求中的某些请求能够完成)
  • 如果10分钟过去了,但没有打开可用的请求“插槽”,则为等待的请求返回错误
  • 接下来运行的请求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
                }
            }
        }
    
    timeout:=time.After(10*time.min)
    滴答声:=时间滴答声(15*时间秒)
    fullcmdfirst:=fmt.Sprintf(“netstat-anp | grep procname | grep已建立| grep-v grep | wc-l”)
    outputfirst,err1first:=exec.Command(“/bin/sh”,“-c”,fullcmdfirst).CombinedOutput()
    如果strconv.ParseFloat(字符串(outputfirst))<100{
    归零
    }
    //继续尝试,直到超时或锁定
    为了{
    挑选{
    //超时!失败,超时错误
    
    case不需要netstats或tickers之类的东西(无论如何,它不会工作-一旦netstat看到您尝试了什么?包括您的代码。您遇到了什么问题?我在互斥体/通道上阅读了一些内容,但找不到类似的内容。我当前的解决方法是os.exec到netstat,并计算已建立的连接。这里有两个不同的问题。请首先回答第一:你可以使用信号量(在Go中,通常只是一个阻塞/缓冲通道)。其他问题更为复杂,有很多不同的解决方案需要考虑。你迄今为止尝试了什么?作为起点:你可以将前一个问题封装到中间件中,就这样。“限制连接是一个完全不同的问题”这意味着什么?我认为这将限制一次100个连接,并让其他连接等待10分钟。为什么会有2个空返回?@apxp只是为了在示例中显式显示。可能处理程序会做的不仅仅是显示的,如果在响应后不返回,可能会导致不希望的行为。@tooptoop4需要在侦听器上进行节流,这更为复杂;客户端的连接超时时间通常比响应时间短得多。例如,如果浏览器无法建立连接,通常会在30秒后超时,但在建立连接后最多会等待5分钟以接收response。所示示例可能有大量连接,但一次最多只能处理100个请求。将建立其他连接,但等待响应。
    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
        }
    }