0

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

我最初的想法是在 a 中运行 Sinatra Web 界面(它基于Rack,适合那些不熟悉 Sinatra 的人)Thread并让它在后台运行。

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

我真的很喜欢 resque 的想法(而且这个名字真的很诙谐),但我不完全确定它是否是我需要的,或者它是否可能是矫枉过正。实际上,我什至不确定如何最好地使用 SinatraEventMachine 来实现它(尽管我没有阅读 resque 的完整文档,只是快速浏览并阅读了示例和用例。)。

想到的另一个想法是在内部使用 Sinatra EventMachine::defer,但这与创建新的本质上不一样Thread吗?

我从来没有用Fibers 做过任何严肃的事情,所以我不知道它们的全部潜力,但它们确实在我脑海中闪过。

那么,哪些(或建议更好的)实践最适合 Ruby PCI。

谢谢

4

2 回答 2

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/

于 2012-11-20T01:44:08.987 回答
0

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

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

于 2012-11-20T05:46:29.993 回答