【问题标题】:How to limit concurrent connections to Go API如何限制 Go API 的并发连接
【发布时间】:2019-09-17 21:59:06
【问题描述】:

我正在启动一个带有 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
            }
        }
    }

【问题讨论】:

  • 你试过什么?包括您的代码。你遇到了什么问题?
  • 我在 mutex/channels 上做了一些阅读,但找不到这样的东西。我目前的解决方法是 os.exec 到 netstat 并计算已建立的连接
  • 这里有几个不同且独立的问题。对于您的第一个:您可以使用信号量(在 Go 中,通常只是一个阻塞/缓冲通道)。其他问题涉及更多,并且有很多不同的解决方案需要推理。到目前为止,您尝试过什么?
  • 你可以将previous包装成一个中间件,就是这样。

标签: go


【解决方案1】:

不需要 netstats 或代码或任何这些(它无论如何都不会工作 - 只要 netstat 看到 connections 完全是一个不同的问题)。只需使用缓冲通道作为信号量;它已经是线程安全的了。

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 分钟之前就已经超时了。

【讨论】:

  • " 限制连接是一个完全不同的问题" 这是什么意思?我认为这会一次限制为 100 个连接并让其他人等待长达 10 分钟
  • 为什么有2个空退货?
  • @apxp 只是为了在示例中明确。据推测,处理程序将做的不仅仅是显示的内容,并且在响应后未能返回可能会导致不良行为。
  • @tooptoop4 需要对监听器进行节流,这更复杂;并且客户端的连接超时时间通常比响应超时时间短得多。例如,浏览器如果无法建立连接,通常会在大约 30 秒后超时,但在建立连接后最多会等待 5 分钟以接收响应。所示示例可能有大量连接,但一次最多只能处理 100 个请求。其他连接将建立,但正在等待响应。
猜你喜欢
  • 1970-01-01
  • 2015-02-27
  • 2019-05-16
  • 2010-10-01
  • 1970-01-01
  • 2020-04-07
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多