在 Django 中用 watchman 自动检测并重载文件更新
The following article is from Python开发精选 Author 南风草木香
【导语】:watchman 是一个由 Facebook 开发的文件监测器,当 Django 项目中的 Python 文件出现改动时,服务器会通过 watchman 自动重载;而当文件没有变化时,watchman 就停止工作。与常用的 StatReloader 相比,这种工作方式占用较少的CPU运行资源,能够起到保护计算机电池的作用。
简介
如果你在一个Django项目中开启服务器,会出现如下结果:
$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (1 silenced).
January 20, 2021 - 04:25:31
Django version 3.1.5, using settings 'db_buddy.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
当你对其中一个Python文件作出更改时,服务器会自动重载。这一功能由一个文件监测器提供,Django在第一行就给出了默认使用的监测器名字-StatReloader。StatReloader虽然简单,但可靠性却很高。它利用一个循环 在每时每刻对你的所有文件进行检查,然而当开发者的项目内容不断增多时,这种方法就变得十分低效。
一个不太知名却更好的选择是使用 Django 支持的 watchman。
项目地址:
https://facebook.github.io/watchman/
watchman是一个高效的文件监测器,由Facebook开源。它从你的操作系统接收文件更改提示,然后把所有变动集合在一起。当没有更改时,watchman就停止工作,这样就可以节省运行资源,延长计算机电池的寿命。当一旦有文件发生改动时,Django在几毫秒之内快速报告。watchman 处理文件变动的方式也很灵活,它将所有变化信息集中起来,用Git整合,等待诸如分支转换这些流程完成后,再进行处理。
安装
在Django项目中使用watchman只需几步,这在runserver文档[1]中 有详细介绍。在此,我将介绍在macOS上对DB Buddy[2](一个Django 3.1项目)使用watchman的主要过程。
首先,我按照网站上的安装指导[3]对watchman进行了安装。在macoS上,这意味着只需要运行brew install watchman
。
简单使用
1、我安装了pywatchman,Django使用这个库来与watchman进行交互。
在requirements.in中添加了pywatchman,从而使用pip-tools[4]中的pip-compile来管理我的requirements:
diff --git a/requirements.in b/requirements.in
index c376421..4407458 100644
--- a/requirements.in
+++ b/requirements.in
@@ -28,2 +28,3 @@ pytest-xdist
python-dotenv
+pywatchman
requests
2、运行pip-compile,将当前版本的pywatchman固定在requirements.txt中,这样就会产生如下变化:
diff --git a/requirements.txt b/requirements.txt
index 95002f9..5d9073c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -155,2 +155,4 @@ pytz==2020.5
# tzlocal
+pywatchman==1.4.1
+ # via -r requirements.in
requests-mock==1.8.0
然后我运行pip install -r requirements.txt来安装已编译的requirements文件。
3、我创建了一个watchman配置文件,以便忽略我的node_modules目录。Django文档提示,忽略这样的非python目录有助于减少负载。我的项目有一个相对最小的JavaScript配置文件,但在node_modules中仍然有14,303
个文件,而所有这些都不需要监测。
根据watchman配置文档[5],
在manage.py
旁边创建了一个.watchmanconfig
文件,其中包括:
{
"ignore_dirs": ["node_modules"]
}
4.我重新启动runserver。Django通过在第一行给出watchmanReloader作为文件监视 器,说明它正在使用watchman:
$ python manage.py runserver
Watching for file changes with WatchmanReloader
Performing system checks...
System check identified no issues (1 silenced).
January 20, 2021 - 07:49:15
Django version 3.1.5, using settings 'db_buddy.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
结论
当服务器完全闲置并且不接收任何请求时,我对更改前后的CPU使用情况作了一个快速对比。使用 StatReloader, runserver大概占用 1.6% 的 CPU 处理器;而使用WatchmanReloader,这一数据减少为 0%,使用 watchman 也显示为 0%。效果非常好!
目前这个项目也相对较小,只有 50 个 Python文件和一些附加文件。由于statReloader 的工作与文件的数量成正比,所以在较大的项目中,这种差异只会更加明显。
参考资料
文档: https://docs.djangoproject.com/en/3.1/ref/django-admin/#runserver
[2]DB Buddy: https://db-buddy.com/
[3]安装指导: https://facebook.github.io/watchman/docs/install.html
[4]pip-tools: https://github.com/jazzband/pip-tools/
[5]watchman配置文档: https://facebook.github.io/watchman/docs/config#ignore_dirs
- EOF -
觉得本文对你有帮助?请分享给更多人
推荐关注「Python开发者」,提升Python技能
点赞和在看就是最大的支持❤️