Manual:Job queue/zh
于2009年(MediaWiki 1.6)引入了作业以便执行长时间运行的任务。 作业被设计为使用批处理来保存许多短任务。
建议您通过命令行完全在后台调度作业的运行。
情况下,作业在web请求结束时运行。通过将$wgJobRunRate
设置为0
来禁用此行为。
runJobs.php
,以确保在作业触及上载文件时系统的权限有被正确地交待。
Cron軟體
您可以使用Cron每小时运行一次作业。将以下内容添加到crontab文件中:
0 * * * * /usr/bin/php /var/www/wiki/maintenance/runJobs.php --maxtime=3600 > /var/log/runJobs.log 2>&1
使用Cron可以很容易地开始,但会使电子邮件通知和模板感觉很慢(最多等待一个小时)。考虑使用以下方法之一来建立一个连续的作业运行器。
持续的服务
如果您有shell权限,并且有创建init脚本的機會的話,那么您可以创建一个简单的服务,在作业可用时运行它们,并限制它们,以防止作业运行者独占服务器的CPU资源:
创建一个bash脚本,例如/usr/local/bin/mwjobrunner
:
创建脚本
#!/bin/bash
# 将MediaWiki安装路径放在下面的行中
MW_INSTALL_PATH="/home/www/www.mywikisite.example/mediawiki"
RUN_JOBS="$MW_INSTALL_PATH/maintenance/runJobs.php --maxtime=3600"
echo 正在启动作业服务……
# 在服务器启动后等待一分钟,以便其他进程有时间启动
sleep 60
echo 开始运行。
while true; do
# 无论-{zh:队列;zh-hans:队列;zh-hant:排序;}-中有多少作业类型都需要尽快运行
# 这些工作应该非常“简易”
php $RUN_JOBS --type="enotifNotify"
# 除此之外,限制每批作业的数量
# --wait参数将在此处暂停执行,直到添加新作业,以避免在運行迴圈的情況下沒有做任何事情
php $RUN_JOBS --wait --maxjobs=20
# 等待几秒钟,让CPU做其他事情,例如处理网络请求等
echo 等待10秒……
sleep 10
done
根据服务器的速度和处理的负载,您可以调整每个周期运行的作业数和每个周期等待的秒数。
使脚本可执行(chmod 755
)。
创建服务
如果使用systemd,请通过创建文件/etc/systemd/system/mw-jobqueue.service
来创建新的服务单元。
将User
参数更改为在web服务器上运行PHP的:
[Unit]
Description=MediaWiki Job runner
[Service]
ExecStart=/usr/local/bin/mwjobrunner
Nice=10
ProtectSystem=full
User=php-fpm
OOMScoreAdjust=200
StandardOutput=journal
[Install]
WantedBy=multi-user.target
启用它并使用以下命令启动它:
sudo systemctl enable mw-jobqueue
sudo systemctl start mw-jobqueue
sudo systemctl status mw-jobqueue
页面请求的作业执行
情况下,在每个web请求结束时,从作业中取出一个作业并执行。
此行为由$wgJobRunRate 配置变量控制。
将此变量设置为1
,将对每个请求运行一个作业。
将此变量设置为0
将完全禁止在web请求期间执行作业,因此您可以从命令行手动或定期运行runJobs.php 。
MediaWiki版本: | ≥ 1.23 |
启用后,将通过打开套接字并向未列出的特殊页面:Special:RunJobs发出内部HTTP请求来执行作业。 另见章节。
性能问题
如果在每个web请求上运行作业的性能负担太大,但无法从命令行运行作业,则可以将$wgJobRunRate 降至1
到0
之间。
这意味着作业将平均每1 / $wgJobRunRate
请求执行一次。
$wgJobRunRate = 0.01;
手动使用
还有一种方法可以手动清空作业,例如,在更改了许多页面上都有使用的模板之后。
简单地运行maintenance/runJobs.php
维护脚本。
例如:
/path-to-my-wiki/maintenance$ php ./runJobs.php
已终止作业
工作可能會因某些原因而失敗。要了解原因,您必須檢查相關的日誌文件。
無論如何,如果工作失敗 3 次(即系統也已經嘗試了該次數),則該工作將被視為「放棄」、不會被再次執行。
有关源代码:
https://doc.wikimedia.org/mediawiki-core/master/php/JobQueue_8php_source.html#l00085
已终止作业是指:
- 不再從runJobs.php 執行
- 不再從Manual:showJobs.php 計數
- 不會自動從資料庫中刪除
- 但有包含在Special:Statistics的計數中
历史
异步
已添加配置变量$wgRunJobsAsync ,以在不需要对作业执行发出内部HTTP请求的情况下强制同步执行作业。
当运行作业时,它将打开一个用于处理作业执行的内部HTTP连接,并将立即将页面内容返回给客户端,而无需等待作业完成。 否则,作业将在同一进程中执行,客户端必须等待作业完成。 当作业未运行时,如果在作业执行过程中发生致命错误,它将传播到客户端,从而中止页面加载。
注意,即使$wgRunJobsAsync设置为true,如果PHP无法打开套接字来发出内部HTTP请求,它也会返回到同步作业执行。 但是,在各种情况下,此内部请求可能会失败,作业不会运行,而不会返回到同步作业执行。 从MediaWiki 1.28.1版和1.27.2版开始,$wgRunJobsAsync现在默认为false。
滞后更新
「滞后更新」机制允许在将所有内容发送到浏览器后,代码的执行被安排在请求的结束之後。 這與某個工作的排序類似,不同的是,它會立即執行,而不是在幾分鐘/幾小時後執行。
DeferredUpdates
在MediaWiki 1.23版中引入,并在MediaWiki 1.27版和1.28版期间进行了重大更改。
该机制的目标是通过减少工作量来加快网络响应速度,并在响应结束后尽快优先处理一些以前属于作业的工作。
一個可滞后的更新可以實現EnqueueableDataUpdate
,以便作為一個工作以進行排序。
這用於核心中的RefreshSecondaryDataUpdate
,例如,這意味著如果任何原因造成更新失敗,則MediaWiki 將回退到作為一個工作去排序,並稍後再次嘗試以履行當前的合約。
MediaWiki 1.22版的改变
在MediaWiki 1.22 中,每个页面请求上的作业执行都发生了更改(Gerrit change 59797),因此,不再在渲染页面的同一个PHP进程中执行作业,而是生成了一个新的PHP CLI命令来在后台执行runJobs.php 。 只有当$wgPhpCli 设置为实际路径或安全模式关闭时,它才会工作,否则将使用旧方法。
这个新的执行方法可能导致一些问题:
- 如果$wgPhpCli 设置为PHP的不兼容版本(例如:过时版本),则作业可能无法运行(1.23中已修复)。
- PHP
open_basedir
限制生效,$wgPhpCli 被禁止(T62208,在1.23中修复)。 - 性能:即使作业为空,也会启动新的PHP进程(T62210,在1.23中修复)。
- 有时,由于stdout和stderr描述符未正确重定向,生成的PHP进程会导致服务器或仅CLI进程挂起(T60719,已在1.22中修复)。
- 它不适用于共享代码(wiki农场),因为它不会向runJobs.php传递额外的必需参数来标识运行作业的wiki(T62698,在1.23中修复)。
- 普通shell限制(如$wgMaxShellMemory , $wgMaxShellTime , $wgMaxShellFileSize )在后台执行的runJobs.php进程上强制执行。
例如,除了将$wgPhpCli 设置为false
之外,无法恢复到旧的请求作业处理,这可能会导致其他问题(T63387)。
它可以通过设置$wgJobRunRate = 0;
完全禁用,但作业将不再在页面请求上运行,您必须显式运行runJobs.php定期运行挂起的作业。
MediaWiki 1.23版的改变
在MediaWiki 1.23版中,放棄了1.22版的執行方法,工作是由 MediaWiki 透過與自身建立 HTTP 連線來觸發的。
它最初被設計為一個API入口點 (Gerrit change 113038),但後來改為未列出的特殊頁面 Special:RunJobs (Gerrit change 118336)。
雖然它解決了1.22 版本中引入的各種錯誤,但仍然需要在新進程中加載大量 PHP 類到記憶體中才能執行工作,並且還會產生新的HTTP請求,伺服器必須處理這些請求。
MediaWiki 1.27版的改变
在MediaWiki 1.25版和MediaWiki 1.26版中,如果維基有自訂的 $wgServerName 配置,使用 $wgRunJobsAsync 有時會導致工作無法執行。此問題已在MediaWiki 1.27版中修復。 T107290
MediaWiki 1.28版的改变
在MediaWiki 1.23版和MediaWiki 1.27版之間,如果MediaWiki請求的伺服器名稱或協定與當前配置的伺服器名稱不匹配(例如,同時支援HTTP和HTTPS,或者MediaWiki位於將請求重定向到HTTPS的反向代理後面),使用 $wgRunJobsAsync 會導致任務無法執行。此問題已在MediaWiki 1.28版中修復。 T68485
MediaWiki 1.29版的改变
在MediaWiki 1.27.0版至1.27.3版以及1.28.0版至1.28.2版中,當$wgJobRunRate 被設定為大於0的值時,錯誤日誌或頁面中可能會出現如下錯誤:
PHP Notice: JobQueueGroup::__destruct: 1 buffered job(s) never inserted
由於此錯誤,某些更新在某些情況下可能會失敗,例如類別頁面上的類別成員未更新,或者最近更改中顯示已刪除頁面的編輯內容——即使您手動執行 runJobs.php 來清除工作排序也是如此。 該問題已被提報為錯誤(T100085),並在1.27.4版和1.28.3版中得到解決。
作业示例
当模版改变时更新链接表
当模板发生更改时,MediaWiki会将一个作业添加到包含该模板的每篇文章的作业中。 每个作业都是读取文章、展开任何模板并相应更新链接表的命令。 在此之前,主文章将保持过时,直到其解析器缓存过期或用户编辑文章。
HTML 缓存清空
更广泛的操作类别可能会导致大量页面的HTML缓存无效:
- 更改图像(必须重新渲染所有缩略图,并重新计算其大小)
- 删除页面(其他页面的所有链接都需要从蓝色变为红色)
- 创建或取消删除页面(如上所述,但从红色到蓝色)
- 更改模板(包含模板的所有页面都需要更新)
除了模板更改之外,这些操作不会使链接表失效,但会使链接到该页面或使用该图像的所有页面的HTML缓存失效。 使页面的缓存无效是一个短操作;它只需要更新单个数据库字段并发送多播数据包来清除缓存。 但如果要做的事情超过1000件,则需要很长时间。默认情况下,每300个操作添加一个作业(请参见$wgUpdateRowsPerJob )。
然而,请注意,即使清除页面的缓存是一项很短的操作,重新分析不在缓存中的复杂页面可能会很昂贵,特别是如果编辑了一个使用率很高的模板,并导致在短时间内清除大量页面,并且您的wiki有大量并发访问者加载大量页面。
这可以通过减少在短时间内清除的页面数量、将$wgUpdateRowsPerJob
减少到一个小数字(例如20)以及将htmlCacheUpdate
的$wgJobBackoffThrottling
设置为一个低数字(例如5)来缓解。
音视频转码
当使用定時媒體處理程式 处理音频和视频文件的本地上传时,作业用于以各种分辨率/格式运行可能非常缓慢的派生代码转换创建。
这些工作不适合在web请求上运行——您需要后台运行程序。
如果可能,建议为webVideoTranscode
和webVideoTranscodePrioritized
的工作类型设置单独的运行器。这两个处理不同的文件子集——第一个用于高分辨率高清视频,第二个用于处理速度更快的低分辨率视频和音频文件。
典型值
当负荷低时,作业可能为零。 在维基媒体,作业实际上几乎从来没有为零。 在低谷时,它可能为几百至一千。 在繁忙的日子,它可能为几百万,但可能很快地变化10%或更多。
Special:Statistics
直到MediaWiki 1.16以前,工作值會被显示在Special:Statistics。 然而从1.17(rev:75272)版本开始这已被移除,并且现在可以通过API:Siteinfo 查看:
当使用MySQL时,API结果中返回的作业数可能稍有不准确,MySQL估计数据库中的作业数。 此数字可能会根据最近添加或删除的作业数量而波动。 对于不支持快速结果大小估计的其他数据库,将给出实际作业数。
对于开发者
代码维护
- Maintained by MediaWiki Interfaces Team.
- Live chat (IRC): #mediawiki-core
- Issue tracker: Phabricator MediaWiki-Core-JobQueue (Report an issue)