我写了一个小的Python应用程序作为守护进程运行.它利用线程和队列.
我正在寻找改变这个应用程序的一般方法,以便我可以在它运行时与它通信.大多数情况下,我希望能够监测其健康状况.
简而言之,我希望能够做到这样的事情:
python application.py start # launches the daemon
后来,我希望能够出现并执行以下操作:
python application.py check_queue_size # return info from the daemonized process
为了清楚起见,我在实现Django启发的语法时没有任何问题.我不知道该怎么做是将信号发送到守护进程(start),或者如何编写守护进程来处理和响应这些信号.
就像我上面说的那样,我正在寻找一般方法.我现在能看到的唯一一个就是告诉守护进程不断记录文件可能需要的所有内容,但我希望有一个不那么混乱的方法.
更新:哇,很多很棒的答案.非常感谢.我想我会看看Pyro和web.py/Werkzeug的方法,因为Twisted比我想要咬一点点多一点.我认为,下一个概念性的挑战是如何在不挂断它的情况下与我的工作线程进行交谈.
再次感谢.
另一种方法:使用Pyro(Python远程对象).
Pyro基本上允许您将Python对象实例发布为可以远程调用的服务.我已经将Pyro用于你描述的确切目的,我发现它工作得非常好.
默认情况下,Pyro服务器守护程序接受来自任何地方的连接.要限制此操作,请使用连接验证程序(请参阅文档),或者提供host='127.0.0.1'
给Daemon
构造函数以仅侦听本地连接.
从Pyro文档中获取的示例代码:
服务器
import Pyro.core class JokeGen(Pyro.core.ObjBase): def __init__(self): Pyro.core.ObjBase.__init__(self) def joke(self, name): return "Sorry "+name+", I don't know any jokes." Pyro.core.initServer() daemon=Pyro.core.Daemon() uri=daemon.connect(JokeGen(),"jokegen") print "The daemon runs on port:",daemon.port print "The object's uri is:",uri daemon.requestLoop()
客户
import Pyro.core # you have to change the URI below to match your own host/port. jokes = Pyro.core.getProxyForURI("PYROLOC://localhost:7766/jokegen") print jokes.joke("Irmen")
另一个类似的项目是RPyC.我没有尝试过RPyC.
怎么让它运行一个http服务器?
这似乎很疯狂,但运行一个简单的Web服务器来管理您的服务器只需几行使用web.py
您还可以考虑创建一个unix管道.
使用werkzeug并使您的守护进程包含基于HTTP的WSGI服务器.
您的守护程序有一组小型WSGI应用程序,用于响应状态信息.
您的客户端只需使用urllib2向localhost发出POST或GET请求:somePort.您的客户端和服务器必须就端口号(和URL)达成一致.
这实现起来非常简单并且可扩展性很强.添加新命令是一项微不足道的工作.
请注意,您的守护程序不必以HTML格式进行响应(但这通常很简单).我们的守护进程使用JSON编码的状态对象响应WSGI请求.
我会使用带有命名管道的扭曲或只是打开一个套接字.看一下echo服务器和客户端示例.您需要修改echo服务器以检查客户端传递的字符串,然后使用任何请求的信息进行响应.
由于Python的线程问题,您将无法响应信息请求,同时继续执行守护程序要执行的任何操作.异步技术或分支其他进程是您唯一真正的选择.
# your server from twisted.web import xmlrpc, server from twisted.internet import reactor class MyServer(xmlrpc.XMLRPC): def xmlrpc_monitor(self, params): return server_related_info if __name__ == '__main__': r = MyServer() reactor.listenTCP(8080, Server.Site(r)) reactor.run()
客户端可以使用xmlrpclib编写,请在此处查看示例代码.
假设您在*nix下,您可以kill
使用shell(以及许多其他环境中的模拟)向正在运行的程序发送信号.要在python中处理它们,请查看信号模块.