如何在Go中编写长时间运行的请求?

huangapple go评论76阅读模式
英文:

How do I write long running requests in go?

问题

故事到目前为止。我们正在考虑放弃使用Perl。候选语言是Go或Node。为此,我们使用Dancer2、Flask、Node和Go编写了简单的包装器,用于我们的长时间运行的数据库查询。我已经将它们全部运行起来,并进行了轻负载的基准测试。然后我决定对这些应用进行压力测试。每个框架都能够处理以下命令:

ab -n 1000 -c 100 http://localhost:8080/

除了Go语言。如果我不限制连接数,就会出现“连接过多”的错误;如果我将连接数限制为100,ab命令会超时并退出。

这是我的Gist链接:https://gist.github.com/2d8473ce576cab5f7c66,其中包含了Go代码。请问我应该做出哪些改变,以便在负载下使用Go服务器?

英文:

Story so far. We are thinking about switching away from perl. The candidates are go or node. For that we wrote simple wrappers in Dancer2, Flask, Node and Go for a long running database query that we have. I had them all up and running, so I benchmarked a bit with light load. Then I decided to stress the applications. Every framework was able to cope with

ab -n 1000 -c 100 http://localhost:8080/

except go. If I did not limit connection then I would get error 'too many connections', if I limited connections to 100, then ab would give timeout error and quit.

My gist https://gist.github.com/2d8473ce576cab5f7c66 with go code. What should I change, so I can use go server under load?

答案1

得分: 2

你的问题看起来像是数据库连接过载的问题,同时连接太多。记住,Go是一种真正并发的语言。

你尝试过将db.SetMaxOpenConns(1000)设置为一个更小的数字,比如db.SetMaxOpenConns(10)吗?

或者你可以通过限制同时运行的goroutine数量来解决这个问题,像这样:

全局声明以下变量:

const maxAtOnce = 50

var limiter = make(chan struct{}, maxAtOnce)

func init() {
    // 填充令牌
    for i := 0; i < maxAtOnce; i++ {
        limiter <- struct{}{}
    }
}

然后在你的getTimeSheet函数开头加入以下代码:

// 获取一个令牌
<-limiter
// 在退出时归还令牌
defer func() {
    limiter <- struct{}{}
}()
英文:

The trouble looks like you are overloading your database with too many simultaneous connections. Remember Go is a truly concurrent language.

Have you tried setting db.SetMaxOpenConns(1000) to a much smaller number, say db.SetMaxOpenConns(10)?

Or alternatively you could limit the number of simultaneously running goroutines like this

Declare these globally

const maxAtOnce = 50

var limiter = make(chan struct{}, maxAtOnce)

func init() {
	// Fill up with tokens
	for i := 0; i &lt; maxAtOnce; i++ {
		limiter &lt;- struct{}{}
	}
}

And in your getTimeSheet put this at the start

// take a token
&lt;-limiter
// give it back on exit
defer func() {
	limiter &lt;- struct{}{}
}()

huangapple
  • 本文由 发表于 2015年3月2日 22:32:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/28812293.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定