因此,我正在我们的 Rails/Unicorn/Nginx 应用程序上调查 MySQL 死锁异常。我发现有时,我们会看到从一个客户端获得 499 状态代码的请求风暴。从这篇文章来看,当客户端意外关闭连接时,nginx 似乎返回 499,或者,嗯,什么。我不太清楚客户是否真的看到了状态码;我无法在本地复制它。
从 nginx 日志来看,在这些请求中,我们最终向客户端写入了 0 个字节。在我的 Rails 日志中,请求没有什么特别之处。他们在正常时间(40-120 毫秒)内完成并返回 302 重定向。
所以,无论如何,对吧?但!造成这种情况的糟糕之处在于,客户端似乎将其看到(或未看到)的任何内容解释为再次尝试其请求的邀请。即使是 POST。我的 Rails 应用程序正在愉快地处理这些请求并在数据库中创建重复条目。有时它会创建很多记录——在一种情况下,我们让客户在大约 10 分钟内重复了大约 6500 次请求。那是……次优的。
我想弄清楚该怎么做。我真正想要的是修复我看到的与 nginx 的任何交互,但我不确定如何——如果客户端在获取数据之前关闭连接,我无法控制它会做什么。
另一种选择(感觉就像一个可怕的黑客)是做一些事情,比如以隐藏的形式包含一个唯一的键(比如,来自一个序列),并在相应的数据库列上有一个唯一的索引。但是这张表上有数百万行,所以我不想轻易地搞乱它的模式。
万一这很重要,请求是通过 HTTPS 完成的。看起来它最常来自我们的一小部分客户。
有没有其他人看过这个(除了这个帖子)?我完全疯了吗?谁能想到一个优雅的解决方案?