簡體   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