英文:
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 < maxAtOnce; i++ {
limiter <- struct{}{}
}
}
And in your getTimeSheet
put this at the start
// take a token
<-limiter
// give it back on exit
defer func() {
limiter <- struct{}{}
}()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论