追逐繁星的孩子

お帰りなさい

首页 标签 归档 分类 关于
uWSGI启动新进程的坑
日期 2018-01-30   |    标签 uWSGI   |    评论

最近项目需要实现一个功能:备份还原SSDB。

项目使用SSDB+uWSGI。

OK,首先SSDB备份有几种方式:

  • 进入./ssdb-cli交互模式

export backup.ssdb

  • 使用ssdb-dump工具

./tools/ssdb-dump ip port output_dir

  • 直接备份数据目录,var目录

当时采用的是第二个方法,python调shell执行备份还原,如果是还原操作还需要重启SSDB。问题出现了(下图):由于重启SSDB相当于开启一个进程。此进程不会完全关闭,会保持time_wait状态。

看到uWSGI一个子进程变成了ssdb进程。这会导致我重启uWSGI服务器会有问题,见下图:

uWSGI父进程被kill,time_wait状态的ssdb子进程被唤醒成父进程。也就是说之前uWSGI进程被ssdb完全取代。再开启uWSGI服务会提示端口被占用。

谷歌、SO无果(我提问的方式不对!)

第二天在官方文档上找到这么一段:

http://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html

If you spawn a new process during a request it will inherit the file descriptors of the worker spawning it - including the socket connected with the webserver/router. If you do not want this behaviour set the close-on-exec option.

也就是说在请求的时候启动了新的进程,该进程会继承uWSGI worker的文件描述符,导致请求的socket不能正常关闭,变成time_wait半关闭状态。配置中添加close-on-exec参数来禁止这种行为。