我正在尝试设计一个具有弹性且高度可用的python API后端服务。核心服务旨在持续运行。该服务必须为我的每个租户独立运行。这是必需的,因为核心服务是阻止服务,并且每个租户的执行需要独立于任何其他租户的服务。
核心服务将由配置服务启动。供应商也是一个持续运行的服务,负责执行内务管理功能,即启动租户注册核心服务,检查所需的环境和属性,停止核心服务等。
目前,我正在使用multiprocessing
模块从供应商服务中生成核心服务的子实例。具有针对每个租户的一个线程的多线程服务也是一种选择,但是如果任何线程崩溃,则具有中断其他租户的服务的缺点。理想情况下,我希望所有这些都作为后台进程运行。问题是
如果我守护配置服务,multiprocessing
将不允许该守护进程创建子进程。这写成here
如果供应者服务死亡,那么所有的孩子都将成为孤儿。我如何从这种情况中恢复过来。
显然,我对那些不遵循此multiprocessing
使用模式的解决方案持开放态度。
答案 0 :(得分:2)
我建议你采取不同的方法。使用分发中提供的系统工具来管理流程的生命周期,而不是自己生成流程。配置器也会简单得多,因为它不需要重复操作系统可以轻松完成的操作。
在Ubuntu / CentOS 6系统上,你可以使用Upstart,与旧的sysvinit(积极的并行化,重生,简单的init配置语法等)相比,它具有很多优点。
SystemD与设计中的upstart类似,在OpenSuse中是默认的。
然后,配置程序只能用于为每个服务创建所需的init配置,并使用子进程模块启动或停止它们。然后,您可以监控您的实例,以防upstart无法重新生成实例,发送警报或尝试再次启动该服务。
使用此方法,可以将所有用户服务实例彼此隔离。如果配置程序崩溃,其余服务将保持运行。
例如,假设您的配置程序在后台运行。它通过AMQP或其他方式获取消息,以创建用户并为该用户启动服务。一个可能的流程是:
init脚本看起来类似于:
description "start Service for [username]"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
# Run before process
pre-start script
end script
exec /bin/su -c "/path/to/your/app" <username>
通过这种方式,您可以将进程管理从配置程序卸载到系统upstart守护程序。您只需要以简单的方式进行作业管理(在创建或删除用户时创建/销毁服务)。
答案 1 :(得分:0)
在debian上,你可以用
包装没有妖魔化的服务start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON --chuid $USER --chdir $DIR -- \
$DAEMON_ARGS
孩子必须在完成任务后死亡。 父进程必须如此简单,只能在主循环中“缓解任务 - 生成子进程”。