Thin 不响应 SIGINT 或 SIGTERM
bundle exec Thin start -p 3111
给出以下输出:
<块引用>使用机架适配器 瘦 Web 服务器(v1.2.11 代号 Bat-Shit Crazy) 最大连接数设置为 1024 监听 0.0.0.0:3111,CTRL+C 停止 ^C
Ctrl-C 不执行任何操作 (SIGINT)。也不杀死(SIGTERM)。
我发现了一些对此行为的参考,但没有解决方案。问题似乎出在 eventmachine(与最新的 Thin 捆绑在一起)、ruby 1.9.2-r290 或 Linux 内核(Ubuntu 10.4 LTS、2.6.38.3-linode32)中。
我的项目会发生这种情况,但全新的 Rails 项目不会发生这种情况。
参考文献:
bundle exec thin start -p 3111
gives the following output:
Using rack adapter
Thin web server (v1.2.11 codename Bat-Shit Crazy)
Maximum connections set to 1024
Listening on 0.0.0.0:3111, CTRL+C to stop
^C
Ctrl-C doesn't do anything (SIGINT). Neither does kill (SIGTERM).
I've found a few references to this behavior, but no solutions. The problem seems to be either in eventmachine (bundled with latest thin), in ruby 1.9.2-r290, or in the linux kernel (Ubuntu 10.4 LTS, 2.6.38.3-linode32).
It happens with my project, but not with a brand new rails project.
References:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测是,要么有什么东西占用了 EventMachine 反应器循环,阻止其退出,要么有什么东西捕获了 SIGINT。
作为前者的一个简单示例,将其放入
config.ru
并使用thin -p 4567 start
运行:如果不捕获 SIGINT,您将获得与捕获时相同的行为它并调用 EM.stop。 EM.stop(至少在纯 ruby 版本中,您可以使用
EVENTMACHINE_LIBRARY="pure_ruby" slim start
运行)设置一个已请求停止的标志,该标志在反应器循环内拾取。如果反应器循环卡在某个步骤上(如上面的情况),那么它不会退出。因此有几个选择:
使用上面捕获 SIGINT 并强制退出的解决方法。这可能会使连接处于不干净的状态,但他们不称其为“快速”和“快速”。 dirty 毫无用处;)
你可以将阻塞代码放入线程或光纤中,这将允许反应器继续运行。
在代码中查找长时间运行的任务或循环,并将它们转换为 EventMachine 感知的。 em-http-request 是一个很棒的外部 http 请求库,并且 em-synchrony 还有其他几个协议(用于数据库连接、tcp 连接池等)。在上面的示例中,这很简单:
EventMachine.add_periodic_timer(1) { puts "EM Running" }
在您的实际代码中,这可能更难追踪,但请查找您生成的任何位置线程并连接它们,或大循环。分析工具可以帮助显示当您尝试退出时正在运行的代码,最后您可以尝试禁用系统和库的各个部分以找出罪魁祸首。
My guess is that either something's tying up the EventMachine reactor loop preventing it from exiting, or something's trapping SIGINT.
As a simple example of the former, put this into
config.ru
and run withthin -p 4567 start
:Without trapping the SIGINT, you get the same behavior as when trapping it and calling EM.stop. EM.stop (at least in the pure ruby version, which you can run with
EVENTMACHINE_LIBRARY="pure_ruby" thin start
) sets a flag that a stop has been requested, which is picked up inside the reactor loop. If the reactor loop is stuck on a step (as in the above case), then it won't exit.So a couple options:
use the workaround above of trapping SIGINT and forcing an exit. This could leave connections in an unclean state, but they don't call it quick & dirty for nothing ;)
you could put the blocking code inside a Thread or a Fiber, which will allow the reactor to keep running.
look for long-running tasks or loops inside your code, and convert these to be EventMachine aware. em-http-request is a great library for external http requests, and em-synchrony has several other protocols (for database connections, tcp connection pools, etc.). In the above example, this is straightforward:
EventMachine.add_periodic_timer(1) { puts "EM Running" }
In your actual code, this might be harder to track down, but look for any places where you spawn threads and join them, or large loops. A profiling tool can help show what code is running when you try to exit, and lastly you can try disabling various parts of the system and libraries to figure out where the culprit is.