记录 Rails 应用程序中的线程内部
我有一个 Rails 应用程序,其中少量操作需要大量计算时间。我发现我可以将处理分成多个线程,并且通过将 JRuby 与多核服务器结合使用,我可以确保所有线程在合理的时间内完成,而不是将这些操作作为后台任务进行管理的复杂性。 (客户已经表达了保留这种方法而不是在后台运行任务的强烈兴趣。)
问题是写入 Rails 记录器在这些线程中不起作用。日志文件中没有显示任何内容。我发现了一些关于这个问题的参考,但没有解决方案。我不介意在代码中插入 put 来帮助调试,但标准输出似乎被 glassfish gem 应用服务器吃掉了。
有没有人成功地在 Rails ruby 线程中完成日志记录,而无需每次都创建新日志?
I've got a Rails application in which a small number of actions require significant computation time. Rather than going through the complexity of managing these actions as background tasks, I've found that I can split the processing into multiple threads and by using JRuby with a multicore sever, I can ensure that all threads complete in a reasonable time. (The customer has already expressed a strong interest in keeping this approach vs. running tasks in the background.)
The problem is that writing to the Rails logger doesn't work within these threads. Nothing shows up in the log file. I found a few references to this problem but no solutions. I wouldn't mind inserting puts in my code to help with debugging but stdout seems to be eaten up by the glassfish gem app server.
Has anyone successfully done logging inside a Rails ruby thread without creating a new log each time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我也因同样的问题而摸不着头脑。对我来说,答案如下:
I was scratching my head with the same problem. For me the answer was as follows:
我理解您对后台任务的担忧,但请记住,在 Rails 中分离线程可能是一件可怕的事情。该框架几乎没有提供多线程处理,这意味着您必须将所有 Rails 对象视为非线程安全的。甚至数据库连接也变得棘手。
至于记录器:标准的 Ruby 记录器类应该是线程安全的。但即使 Rails 使用它,您也无法控制 Rails 应用程序对其执行的操作。例如,基准测试机制将通过切换级别来“静音”记录器。
我会避免使用 Rails 记录器。如果要使用线程,请在线程内创建一个新记录器来记录该操作的消息。如果您不想为每个线程创建一个新日志,您还可以尝试在运行时创建一个每个线程都可以访问的线程安全日志记录对象。
在你的位置,我可能会再看看后台作业解决方案。虽然 DRb 看起来像一场噩梦,但“bj”似乎又好又容易;尽管需要一些工作才能使其与 JRuby 一起运行。还有使用 JRuby 中的 Java 调度程序的替代方案,请参阅 http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails
I understand your concerns about the background tasks, but remember that spinning off threads in Rails can be a scary thing. The framework makes next to no provisions for multithreading, which means you have to treat all Rails objects as not being thread-safe. Even the database connection gets tricky.
As for the logger: The standard Ruby logger class should be thread safe. But even if Rails uses that, you have no control over what the Rails app is doing to it. For example the benchmarking mechanism will "silence" the logger by switching levels.
I would avoid using the rails logger. If you want to use the threads, create a new logger inside the thread that logs the messages for that operation. If you don't want to create a new log for each thread, you can also try to create one thread-safe logging object in your runtime that each of the threads can access.
In your place I'd probably have another look at the background job solutions. While DRb looks like a nightmare, "bj" seems nice and easy; although it required some work to get it running with JRuby. There's also the alternative to use a Java scheduler from JRuby, see http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails