【问题标题】:Exposing python daemon as a service将 python 守护进程公开为服务
【发布时间】:2023-08-21 04:11:01
【问题描述】:

因此,我已经能够从 python 脚本中提取两个非常有价值的特性。第一个是能够从命令行将 python 函数作为服务运行。为简单起见,假设 python 脚本采用命令行参数。大致如下:

import sys

def foo():
    return "%s is your last argument!" % sys.argv[-1]

foo()

然后我将通过运行python file.py somearg 全局访问它,此外,我可以编写一个 supervisord 脚本来守护一个脚本并让它在内存中运行。我现在发现自己处于同时需要这两个功能的位置,但我不确定从哪里开始。为了清楚起见,我基本上有以下几点:

if __name__ == "__main__":
    big_file = open(slow_loader)
    foo(big_file)

理想情况下,一旦它运行,我会将整个big_file 保存在内存中,并能够通过运行类似于原始python file.py somearg 的方法来访问foo 方法,具体取决于big_file。不过,我不确定如何从这里取得进展。

任何帮助,即使它只是指向某些文档的链接,也会非常有帮助。提前,我意识到我可以将它包装在一个浅瓶应用程序中并通过http 请求运行它,但出于保密协议的原因,我需要通过内部 shell 命令运行的东西。

【问题讨论】:

  • 是否有可能引入 redis 或 memcached 之类的东西?
  • @dano 我完全可以添加任何外部服务,但不能替换 big_file。从技术上讲,我实际上无法触及file.py 的来源,但我对自省充满信心,一旦主要解决方案出现,我就可以将其应用于此上下文。

标签: python linux unix service daemon


【解决方案1】:

仅仅因为我喜欢zmq和gevent,我可能会做这样的事情:

server.py

import gevent
import gevent.monkey
gevent.monkey.patch_all()
import zmq.green as zmq
import json

context = zmq.Context()
socket = context.socket(zmq.ROUTER)
socket.bind("ipc:///tmp/myapp.ipc")

def do_something(parsed):
    return sum(parsed.get("values"))

def handle(msg):
    data = msg[1]
    parsed = json.loads(data)
    total = do_something(parsed)
    msg[1] = json.dumps({"response": total})
    socket.send_multipart(msg)

def handle_zmq():
    while True:
        msg = socket.recv_multipart()
        gevent.spawn(handle, msg)

if __name__ == "__main__":
    handle_zmq()

然后你的命令行工具就会有一个 client.py,比如

import json
import zmq

request_data = {
        "values": [10, 20, 30 , 40],
        }

context = zmq.Context()
socket = context.socket(zmq.DEALER)
socket.connect("ipc:///tmp/myapp.ipc")
socket.send(json.dumps(request_data))
print socket.recv()

显然这是一个人为的例子,但你应该明白这个想法。或者,您也可以为此使用 xmlrpc 或 jsonrpc 之类的东西。

【讨论】:

  • 是的,我打算建议使用基于 AMQP 的东西,但 ZeroMQ 也可以正常工作。
  • 抱歉,您能否对gevent.spawngevent.monkey.patch_all 位进行更多解释?
  • gevent 是一个基于greenlet 的异步网络框架。该调用在 greenlet 中运行 handle,因此它可以异步处理 msg,同时仍侦听新请求。请注意,它只会使 I/O 异步。它可能对你有用也可能没用,这取决于你在实现 handle 时所做的工作。如果您正在做一些受 CPU 限制的事情,您可能想改用multiprocessing。如果您不希望并发请求进入server.py,那么异步可能根本没有多大意义。