Python mod_wsgi:通过Inotify重新加载代码-不是每N秒一次
到目前为止,我遵循以下建议重新加载代码: 这有一个缺点,即代码更改仅每N秒检测一次。我可以使用N=0.1,但这会导致无用的磁盘IO AFAIK linux内核的inotify回调可以通过python获得 有没有更快的方法检测代码更改并重新启动wsgi处理程序 我们在linux上使用守护程序模式 为什么要为mod_wsgi重新加载代码 人们对我为什么想要这个很感兴趣。以下是我的设置: 大多数人使用“Python mod_wsgi:通过Inotify重新加载代码-不是每N秒一次,python,django,mod-wsgi,inotify,Python,Django,Mod Wsgi,Inotify,到目前为止,我遵循以下建议重新加载代码: 这有一个缺点,即代码更改仅每N秒检测一次。我可以使用N=0.1,但这会导致无用的磁盘IO AFAIK linux内核的inotify回调可以通过python获得 有没有更快的方法检测代码更改并重新启动wsgi处理程序 我们在linux上使用守护程序模式 为什么要为mod_wsgi重新加载代码 人们对我为什么想要这个很感兴趣。以下是我的设置: 大多数人使用“manage.py runserver”进行开发,使用其他部署进行生产 在我的上下文中,我们已经自
manage.py runserver
”进行开发,使用其他部署进行生产
在我的上下文中,我们已经自动化了新系统的创建,而prod和开发系统基本上是相同的
一个操作系统(linux)可以承载N个系统(虚拟环境)
开发人员可以使用runserver或mod_wsgi。使用runserver的好处是易于调试,mod_wsgi
的好处是不需要先启动服务器
mod_wsgi的好处是,您知道URL:https://dev-server/system-name/myurl/
使用runserver时,您不知道端口。用例:您希望从内部wiki链接到开发系统
我们过去使用的mod_wsgi重新加载代码的一个肮脏的方法:
maximum requests=1
,但这很慢。根据i-notify信号,您可以使用inotify hooktables运行所需的任何命令(这是我的源链接:)
查看表之后,您可以重新加载apache的代码
对于您的具体问题,应该是这样的:
inotify-hookable --watch-directories sources/ --recursive --on-modify-command './code_reload.sh'
在前面的链接中,要执行的命令只是一个简单的touch flask/init.wsgi
因此,整个代码(添加被忽略的文件)是:
如这里所述:,如果启用了WSGIScriptReloading
,则只需触摸该文件即可。它将导致重新加载整个代码(而不仅仅是配置文件)。但是,如果愿意,可以设置任何其他脚本来重新加载代码
在谷歌搜索了一段时间后,它似乎是解决这个问题的一个非常标准的解决方案,我认为您可以将它用于您的应用程序 预备赛。
开发人员可以使用runserver或mod_wsgi。使用runserver具有
好处是调试容易,mod_wsgi的好处是
您不需要先启动服务器
但是您需要先安装服务器,这需要花费大量的精力。服务器也需要在这里启动,尽管您可以将其配置为在引导时自动启动
如果您在端口80或443上运行(通常是这种情况),则服务器只能由root用户启动。如果需要重新启动,您必须再次请求超级用户的帮助。因此/manage.py runserver
在这里得分很高
mod_wsgi的好处是,您知道URL:
这与dev服务器没有什么不同。默认情况下,它在端口8000上启动,因此您可以按以下方式访问它。如果您想在开发服务器上使用SSL,您可以使用一个包,例如或将nginx放在django开发服务器前面
使用runserver时,您不知道端口。用例:您希望从>内部wiki链接到开发系统
使用runserver,端口的定义如上所述。您可以通过以下方式使其在不同的端口上侦听:
./manage.py runserver 0.0.0.0:9090
请注意,如果您将开发服务器放在apache(作为反向代理)或NGINX之后,我上面提到的重启问题等在这里不适用
因此,简而言之,对于开发工作,无论您使用mod_wsgi做什么,都可以使用django开发服务器(aka./manage.py runserver)来完成
Inotify
现在我们终于进入主题了。假设您已经安装了inotify工具
,那么您可以在shell中键入它。你不需要写脚本
while inotifywait -r -e modify .; do sudo kill -2 yourpid ; done
这将导致在以下情况下重新加载代码
。。。通过将守护程序模式与单个进程一起使用,可以发送SIGINT
使用“kill”命令向守护进程发送信号,或者
应用程序在指定URL时向自身发送信号
触发。
参考:
或者
while inotifywait -r -e modify .; do touch wsgi.py ; done
什么时候
。。。使用daemon模式,与任意数量的进程和进程
mod_wsgi 2.0的重新加载机制已经启用,那么您所需要的一切
要做的是触摸WSGI脚本文件,从而更新其修改
时间,守护进程将自动关闭并重新启动
下次他们收到请求时
在这两种情况下,我们都使用-r
标志通知inotify监视子目录。这意味着每次保存.css
或.js
文件时,apache都将重新加载。但是如果没有-r标志,子文件夹中对python代码的更改将不会被检测到。要充分利用这两个世界,请使用--exclude
指令删除css、js、图像等
IDE保存自动备份文件时会发生什么情况?或者vim保存.swp
文件?这也会导致代码重新加载。因此,您也必须排除这些文件类型
因此,简而言之,免费复制django开发服务器所做的工作是一项艰巨的工作。使用您注意到的
inotify
,当收到通知时,通过使用os.getpid()获取进程ID向自己发送SIGINT
信号
。更新代码后只触摸wsgi.py有什么不对?@e4c5为什么我不喜欢用手触摸wsgi.py:我很懒,我想做的事情越少越好,因为这会让我更快。这可能会让你更快,但可能会让重新加载过程慢很多!您是否考虑过使用fabric之类的工具来自动更新站点?这绝对是一种懒惰的做法it@e4c5我不想把这个用于生产。我想测试一下。
while inotifywait -r -e modify .; do touch wsgi.py ; done