与正在运行的 python 守护进程通信
我编写了一个作为守护进程运行的小型 Python 应用程序。 它利用线程和队列。
我正在寻找更改此应用程序的通用方法,以便我可以在它运行时与其进行通信。 主要是我希望能够监控它的健康状况。
简而言之,我希望能够做这样的事情:
python application.py start # launches the daemon
稍后,我希望能够一起做这样的事情:
python application.py check_queue_size # return info from the daemonized process
需要明确的是,我在实现受 Django 启发的项目时没有任何问题句法。 我不知道如何向守护进程(启动)发送信号,或者如何编写守护进程来处理和响应此类信号。
正如我上面所说,我正在寻找通用方法。 我现在唯一能看到的是告诉守护进程不断地将可能需要的所有内容记录到文件中,但我希望有一种不那么混乱的方法来实现它。
更新:哇,很多很棒的答案。 非常感谢。 我想我会看看 Pyro 和 web.py/Werkzeug 方法,因为 Twisted 比我现在想要的要多一些。 我想,下一个概念挑战是如何在不挂起工作线程的情况下与它们对话。
再次感谢。
I wrote a small Python application that runs as a daemon. It utilizes threading and queues.
I'm looking for general approaches to altering this application so that I can communicate with it while it's running. Mostly I'd like to be able to monitor its health.
In a nutshell, I'd like to be able to do something like this:
python application.py start # launches the daemon
Later, I'd like to be able to come along and do something like:
python application.py check_queue_size # return info from the daemonized process
To be clear, I don't have any problem implementing the Django-inspired syntax. What I don't have any idea how to do is to send signals to the daemonized process (start), or how to write the daemon to handle and respond to such signals.
Like I said above, I'm looking for general approaches. The only one I can see right now is telling the daemon constantly log everything that might be needed to a file, but I hope there's a less messy way to go about it.
UPDATE: Wow, a lot of great answers. Thanks so much. I think I'll look at both Pyro and the web.py/Werkzeug approaches, since Twisted is a little more than I want to bite off at this point. The next conceptual challenge, I suppose, is how to go about talking to my worker threads without hanging them up.
Thanks again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
另一种方法:使用 Pyro (Python 远程处理对象)。
Pyro 基本上允许您将 Python 对象实例发布为可以远程调用的服务。 我已经将 Pyro 用于您所描述的确切目的,并且我发现它工作得非常好。
默认情况下,Pyro 服务器守护进程接受来自任何地方的连接。 要限制此情况,请使用连接验证器(请参阅文档),或向
Daemon
构造函数提供host='127.0.0.1'
以仅侦听本地连接。示例代码取自 Pyro 文档:
Server
Client
另一个类似的项目是 RPyC。 我没有尝试过 RPyC。
Yet another approach: use Pyro (Python remoting objects).
Pyro basically allows you to publish Python object instances as services that can be called remotely. I have used Pyro for the exact purpose you describe, and I found it to work very well.
By default, a Pyro server daemon accepts connections from everywhere. To limit this, either use a connection validator (see documentation), or supply
host='127.0.0.1'
to theDaemon
constructor to only listen for local connections.Example code taken from the Pyro documentation:
Server
Client
Another similar project is RPyC. I have not tried RPyC.
让它运行一个 http 服务器怎么样?
这看起来很疯狂,但运行一个简单的网络服务器来管理你的
服务器使用 web.py 只需要几行
您也可以考虑创建一个 unix 管道。
What about having it run an http server?
It seems crazy but running a simple web server for administrating your
server requires just a few lines using web.py
You can also consider creating a unix pipe.
使用 werkzeug 并使您的守护进程包含基于 HTTP 的 WSGI 服务器。
您的守护进程有一组小型 WSGI 应用程序,用于响应状态信息。
您的客户端只需使用 urllib2 向 localhost:somePort 发出 POST 或 GET 请求。 您的客户端和服务器必须就端口号(和 URL)达成一致。
这实现起来非常简单并且可扩展性非常好。 添加新命令是一个简单的练习。
请注意,您的守护程序不必以 HTML 形式响应(尽管这通常很简单)。 我们的守护进程使用 JSON 编码的状态对象响应 WSGI 请求。
Use werkzeug and make your daemon include an HTTP-based WSGI server.
Your daemon has a collection of small WSGI apps to respond with status information.
Your client simply uses urllib2 to make POST or GET requests to localhost:somePort. Your client and server must agree on the port number (and the URL's).
This is very simple to implement and very scalable. Adding new commands is a trivial exercise.
Note that your daemon does not have to respond in HTML (that's often simple, though). Our daemons respond to the WSGI-requests with JSON-encoded status objects.
我会使用带有命名管道的twisted 或只是打开一个套接字。 查看 echo 服务器和客户端示例。 您需要修改回显服务器以检查客户端传递的某些字符串,然后响应任何请求的信息。
由于 Python 的线程问题,您将无法响应信息请求,同时继续执行守护程序本来应该执行的任何操作。 异步技术或分叉另一个进程是您唯一真正的选择。
I would use twisted with a named pipe or just open up a socket. Take a look at the echo server and client examples. You would need to modify the echo server to check for some string passed by the client and then respond with whatever requested info.
Because of Python's threading issues you are going to have trouble responding to information requests while simultaneously continuing to do whatever the daemon is meant to do anyways. Asynchronous techniques or forking another processes are your only real option.
客户端可以使用 xmlrpclib 编写,请在此处查看示例代码。
client can be written using xmlrpclib, check example code here.
假设您在 *nix 下,您可以从 shell(以及许多其他环境中的类似方式)使用
kill
向正在运行的程序发送信号。 要在 python 中处理它们,请查看 signal 模块。Assuming you're under *nix, you can send signals to a running program with
kill
from a shell (and analogs in many other environments). To handle them from within python check out the signal module.您可以将其与 Python 远程对象 Pyro (http://pythonhosted.org/Pyro4/) 相关联。 它允许您远程访问 python 对象。 它易于实现,开销低,并且不像 Twisted 那样具有侵入性。
You could associate it with Pyro (http://pythonhosted.org/Pyro4/) the Python Remote Object. It lets you remotely access python objects. It's easily to implement, has low overhead, and isn't as invasive as Twisted.
您可以使用
multiprocessing
管理器(https://docs.python.org/3/library/multiprocessing.html#managers" rel="nofollow noreferrer">https:// /docs.python.org/3/library/multiprocessing.html#managers):服务器示例:
客户端示例:
You can do this using
multiprocessing
managers (https://docs.python.org/3/library/multiprocessing.html#managers):Example server:
Example client: