登录
首页 >  Golang >  Go问答

限制Go API的并发访问

来源:stackoverflow

时间:2024-03-20 14:45:28 335浏览 收藏

在使用 Go API 开发 HTTP 服务时,限制并发请求访问对于确保服务稳定性至关重要。通过实现一个简单的机制,您可以控制并发请求的数量,避免服务超载和性能下降。

问题内容

我正在使用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
            }
        }
    }

解决方案


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

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>