繁体   English   中英

Rails在生产环境中调试

[英]Rails debugging in production environment

我正在创建一个Twitter应用程序,每次用户更新页面时,它都会重新加载来自Twitter的最新消息,并将它们保存到本地数据库,除非它们之前已经创建过。 这在开发环境(数据库:sqlite3)中运行良好,但在生产环境(mysql)中,它总是会再次创建消息,即使它们已经创建过。

twitter_id检查消息创建,每条消息都有:

msg = Message.find_by_twitter_id(message_hash['id'].to_i)
if msg.nil?
  # creates new message from message_hash (and possibly new user too)
end
msg.save

显然,在生产环境中,由于某些原因,它无法通过twitter id找到消息(当我查看数据库时,它已经正确保存了所有属性)。

通过这个长篇介绍,我想我的主要问题是如何调试这个? (除非你已经对主要问题有了答案,当然:)当我查看production.log时,它只显示如下内容:

Processing MainPageController#feeds (for 91.154.7.200 at 2010-01-16 14:35:36) [GET]
Rendering template within layouts/application
Rendering main_page/feeds
Completed in 9774ms (View: 164, DB: 874) | 200 OK [http://www.tweets.vidious.net/]

...但不是数据库请求,logger.debug文本或任何可以帮助我找到问题的内容。

您可以通过在config / environment / production.rb中设置日志级别来更改生产中的日志级别

config.log_level = :debug

这将记录sql以及你以前在dev中看到的所有其他东西 - 它会使应用程序变慢,并且你的日志会很大,所以请谨慎使用。

但至于问题背后的实际问题......

可能是因为多个连接访问mysql?

如果尚未提交twitter条目,那么从另一个连接查询它们将不会返回它们,因此如果在提交之前调用它们的查询,那么您将找不到它们,而是将插入相同的条目再次。 在具有许多用户的生产环境中,这比在sqlite上单独测试更有可能发生。

由于您使用的是mysql,因此您可以使用twitter id上的唯一键来防止欺骗,然后在尝试插入欺骗时捕获ActiveRecord异常。 但这意味着处理错误,这不是处理这个问题的一种很好的方式(尽管我建议将其作为防止欺骗的备份方法 - mysql对此有好处,使用它)。

您还应该阻止尝试插入欺骗。 一种方法是在公共记录上使用锁定,比如说所有推文都与之相关的用户记录,这样另一个进程就无法尝试为用户添加推文,直到它能够获得该锁定(只有在事务已完成),因此阻止同时提交相同的信息。

我在向数据库保存电子邮件时遇到了类似的问题,我同意Andrew的意见,将日志级别设置为调试,以获取有关具体情况的更多信息。

至于实际问题,您可以尝试向数据库添加唯一索引,以防止使用相同参数保存两个项目。 这就像validates_uniqueness但在数据库级别,并且非常有效: Mysql在Rails中约束数据库条目

例如,如果您不希望数据库中的消息对象具有重复的文本正文,并且重复的推特ID(这意味着同一个人在Twitter上发送相同的文本)。 然后,您可以将其添加到迁移中:

add_index( :message, [:twitter_id, :body] , :unique => true)

在你告诉Rails中的一个对象保存之前需要花费一些时间,在实际进入数据库之前,这可能是为什么id的查询还没有找到任何东西。

对于生产服务器,我建议设置一个rollbar来报告生产服务器中所有未处理的错误和异常。

您还可以存储一堆有用的信息,例如http请求,请求的用户,调用错误的代码等等,或者每次生产服务器上发生一些未处理的异常时发送电子邮件通知。

这是一篇关于在rails调试的简单文章 ,可以帮助你。

暂无
暂无

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

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