繁体   English   中英

Sidekiq在AWS RDS上返回“ ActiveRecord :: ConnectionTimeoutError:无法在5.000秒(等待的5.000秒)内获得数据库连接”

[英]Sidekiq returns “ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)” on AWS RDS

我正在使用Sidekiq在AWS服务器上创建PDF文档,以在后台处理此作业。

在创建PDF文件的过程中,[Rails]应用程序正在池化数据库以检查是否已创建PDF文件(间隔:2秒)。

今天早上,我在Sidekiq端收到此错误消息:

ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)

我正在将Amazon RDS与MySQL一起使用。

作为一个临时解决方案,我将database.ymlpool参数从10增加到了30 ,但是我意识到这只是一个临时补丁。

如何正确修复?

谢谢

我认为您的解决方案实际上是正确的。 ActiveRecord::ConnectionPool是基于线程的,即它尝试为每个要与数据库一起使用的线程获取单独的连接。 如果有更多线程想要访问数据库,则连接池的总大小(使用database.ymlpool选项配置),如果释放了来自其他线程的连接,则ConnectionPool尝试默认最多等待5秒。 在这5秒钟的超时后,将引发ActiveRecord::ConnectionTimeoutError异常。

现在, Sidekiq 默认使用25个工作线程 因此,在更高的负载下,完全有可能有多达25个作业(线程)尝试同时访问数据库。 如果将pool设置为10,则多余的工作人员必须等待其他工人完成,并且可能某些线程不得不等待太长时间。

因此,要么像您那样将连接池的大小至少增大到至少稍大于25(sidekiq工作程序的数量), 要么通过像sidekiq -c 5那样运行它以减少工作程序来运行sidekiq -c 5 最后,始终确保您在MySQL端允许足够的传入连接(默认情况下,它超过100个)。

轮询通常不能扩展为解决方案。

在不了解您的应用程序结构的更多信息的情况下,我很想利用来自诸如gem -ruby之类的gem的并发构造。

具体而言,PDF文件的创建与“ 未来”或“ 承诺”的概念非常接近

我会考虑重新组织您的工人:

  1. 您的PDF生成代码应为Promise。 它应该只打开数据库连接足够长的时间,以将生成的PDF写入数据库。 而不是同时进行pdf生成。

  2. 您的主要应用程序代码应照常在Sidekiq上增加PDF生成承诺。 而不是轮询数据库; 此代码只是等待Promise完成或失败; 如果Promise成功完成,则PDF位于数据库中;如果Promise失败,则具有异常跟踪等。

与往常一样,ymmv

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM