“从外部”控制Ruby应用程序的实践

时间:2012-11-19 23:12:27

标签: ruby sinatra ipc ruby-1.9 eventmachine

所以,我有一个长期运行的Ruby进程,可以处理各种各样的事情,具体取决于它告诉你做什么(具有二进制消息的EventMachine TCP服务器)。现在,我想让某些人能够通过Web界面监控,更改,关闭给定的流程。我计划使用Sinatra.rb,但我愿意接受更好的选择。

我最初的想法是在Thread内运行Sinatra网络界面(它基于Rack,对于那些不熟悉Sinatra的人)并让它在后台运行。

但是,我认为如果我这样做会影响性能,所以我决定研究IPC能力和Ruby的替代实现(resque,内存共享,{{3}等等)。

我真的很喜欢resque的想法(名字真的很机智),但我不完全确定它是否是我需要的,或者它是否有点矫枉过正。实际上,我甚至不确定如何最好地使用Sinatra EventMachine实现它(尽管我没有阅读resque的完整文档,只是快速扫描并阅读示例并使用 - 的情况。)。

我想到的另一个想法是在EventMachine::defer内使用Sinatra,但这与创建新的Thread基本相同吗?

我从未使用Fiber做过任何严肃的事情,所以我不知道他们的完整的潜力,但他们确实在我的脑海里。

那么,哪些(或建议更好的)实践对Ruby PCI来说是最好的。

由于

2 个答案:

答案 0 :(得分:2)

我建议您使用信号与正在运行的进程进行通信。

通过这种方法,您使用的框架无关紧要,
虽然我最好的推荐是Espresso Framework

所以这是交易。您可以通过kill界面向您的流程发送大量信号。

可以从另一个Ruby进程的命令行发送信号。

您需要的只是捕获/捕获应用内发送的信号。

示例:内部控制过程:

# build your app

Signal.trap("USR1") do
  # do some stuff here
end

Signal.trap("USR2") do
  # do another stuff here
end

# run your app

当您启动应用时,请务必获取其PID

拥有PID,您可以通过kill向您的应用发送信号 (不,它不会杀死你的应用程序,除非你发送明确的信号)。

然后从另一个Ruby进程中你可以做到:

Process.kill "USR1", PID

或直接从命令行:

kill USR2 PID

你的应用程序将捕获/捕获发送信号并执行相应的操作。

确保将PID替换为受控应用的实际进程ID。

Unicorn Web服务器成功使用了这种做法。

以下是信号列表:

http://en.wikipedia.org/wiki/Unix_signal

在Ruby中使用信号的一些见解:

https://jellyjelly.net/blog/2010/04/27/unix-signal-programming-in-ruby/

答案 1 :(得分:0)

您可以使用本地消息队列,例如RabbitMQ(AMQP的实现),但这实际上与您提到的使用Redis相同。

这种方法不依赖于OS特定的进程间通信机制。所以,是的,你将运行另一项服务,但你不会加入任何低级别。当需要扩展时,这可能是一件非常好的事情。