5

我在 Goliath (eventmachine) 下使用带有 em_mysql2 的 activerecord。我的用户模型发生了最奇怪的事情。当我第一次对 /users 进行 POST 时,一切都按预期工作。当我进行第二次 POST 时,出现错误。

Mysql2::Error: This connection is still waiting for a result, try again once you have the result: INSERT INTO `users` (... and so on ...)

我的任何其他模型或路线都不会发生这种情况。我假设如果数据库连接处于混乱状态,我会在其他请求上看到相同的错误,但不会 - 所有其他数据库更新和 GET 请求似乎都工作得很好。

有谁知道这只能发生在我的 Users 模型中并且仅发生在 User.save 操作中?活动记录是否以某种方式存储它用于执行 Model.save 并重新使用它的数据库连接?

编辑:

当我写这个问题时,我不知何故没有提到我使用 ActiveRecord 作为 ORM。我也没有提到我正在异步向 Mongo 数据库发送请求以获取用户身份验证信息。

我的解决方案:

事实证明,这个错误唯一发生的时候是 Mongo 的响应在 MySQL 的响应之前返回,这导致 MySQL 响应被不同的 Fiber 接收,而不是发出请求的 Fiber。由于我使用的 MySQL2 光纤实现使用光纤的 objectID 来管理连接,这似乎导致了问题。

ActiveRecord + MySql2 + Fibers + Goliath 中的整体连接池不是完全支持的配置。(不过从那时起可能会有一些进展)

4

1 回答 1

0

使用带有 em-synchrony 的连接池。此处仅使用一个连接会失败,因为请求来自 Goliath,而 MySQL 查询仍在等待结果,因为您不能在单个连接上拥有多个活动查询。

像这样包装连接:

db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
  Mysql2::EM::Client.new
end

如果所有连接都在使用中,池会确保请求等到连接可用。

但是,连接池的大小需要调整,具体取决于您的数据库可以处理的内容以及您期望的流量。我从 5-10 左右开始,但它是一个相对较低的流量服务,至少在开始时是这样。这使我们的连接问题消失了。

于 2011-11-06T21:35:29.337 回答