【发布时间】:2022-12-08 00:52:21
【问题描述】:
使用 Go 例程,我为每个例程设置了最长 30 秒的截止日期,代码如下所示:
func processLibs(ctx context.Context, libs []Library) {
for _, lib := range libs {
go processLib(ctx, lib)
}
}
func processLib(ctx context.Context, lib Library) {
cancelContext, cancel := context.WithTimeout(ctx, time.Second * 30)
defer cancel()
if err := persistLib(ctx, lib); err != nil {
log.Error("error persisting library", log.Err(err))
}
}
其中 persistLib 对数据库执行 7 次查询(最大连接数和最大空闲连接数等于 5),并向另一台服务器发出一个请求(传出请求时间正常)。事实上,我知道 libs 的长度小于或等于 100。
我遇到的问题是,有时候,我有一批错误(大约 20% 的 go 例程)说上下文已过期,但我发现真的很奇怪,一个 go 例程只需要 30 秒(测量一下,应该没问题)。
我尝试将 go 例程的数量减少到 70 或 50,但问题仍然存在。我也尝试检查性能改进,但一些 go 例程在第一个查询中间发送截止日期错误,其中一些在 go 例程执行结束时发送,这取决于。
我的数据库是 MySQL 8.0,我使用的是 GO 1.19。
【问题讨论】:
-
“我觉得一个 go 例程只需要 30 秒就很奇怪”为什么这很奇怪?您有 30 秒的超时时间,我希望超时的运行正好需要 30 秒,因为那是它应该停止的地方。
-
如果 persistLib 函数是一个长时间运行的任务,您可以简单地尝试更长的超时时间。也许将其更改为 60 秒?