目的
多进程服务高可用目的暂定为两个:
- 任务超时(计算超时,或者内部死锁),会出现timeout,任务计算失败。
- 子进程挂掉(比如动态基线卡爆子进程, 手动kill -9子进程),主进程会重新启用子进程,并分配任务。丢失的任务,可以从日志中看到
高可用暂不支持:
- 暂不支持任务回收,即丢失的任务重新计算
不支持任务回收因为不确定子进程何时会挂掉,所以对子进程爆掉时的任务难处理
实现方式:
- 子进程挂掉使用multiprocess里的pool的机制:若主进程接到任务,则使用pool.apply_async产生子进程并计算;若进程卡死,则pool会自动创建新的子进程
- 超时机制为:在子进程里使用signal.alarm函数,对子进程状态进行监控
出现的问题
在pool中,子进程挂掉后,新启用的子进程不能工作
尝试思路
- 根据系统级别日志出现的segfault,尝试修复打包环境,修复环境后未解决问题
- 尝试使用主进程监控子进程的形式,尝试实现高可用,结果为:mac好用,Linux不好用
- 尝试修改超时监控策略,结果不好用
- 尝试修改进程启动策略,结果不好用
- 使用gdb调试不工作进程,进展为:认为可能存在死锁问题
问题产生原因:
- 子进程使用logging时,拷贝上下文时,会把主进程的锁拷贝进来,但此时主进程可能并没有release掉,因此在子进程acquire锁时,获取不到主进程的锁,最终产生死锁,导致子进程不工作
问题解决方式:
- 在子进程使用logging之前,删除继承过来的logging处理器(此时删除掉了继承过来的锁),并重新创建处理器。
- logging.config.dictConfig 肯定存在bug,避免在子进程中使用logging.config.dictConfig函数