Manual:Job queue/zh

Category:Pages using deprecated NoteTA template#%20

于2009年(MediaWiki 1.6)引入了作业以便执行长时间运行的任务。 作业被设计为使用批处理来保存许多短任务。

建议您通过命令行完全在后台调度作业的运行。 情况下,作业在web请求结束时运行。通过将$wgJobRunRate 设置为0来禁用此行为。

您应该以与web服务器相同的运行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降至10之间。 这意味着作业将平均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

已终止作业是指:

历史

异步

已添加配置变量$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请求上运行——您需要后台运行程序。

如果可能,建议为webVideoTranscodewebVideoTranscodePrioritized的工作类型设置单独的运行器。这两个处理不同的文件子集——第一个用于高分辨率高清视频,第二个用于处理速度更快的低分辨率视频和音频文件。

典型值

当负荷低时,作业可能为零。 在维基媒体,作业实际上几乎从来没有为零。 在低谷时,它可能为几百至一千。 在繁忙的日子,它可能为几百万,但可能很快地变化10%或更多。

Special:Statistics

直到MediaWiki 1.16以前,工作值會被显示在Special:Statistics。 然而从1.17(rev:75272)版本开始这已被移除,并且现在可以通过API:Siteinfo查看:

当使用MySQL时,API结果中返回的作业数可能稍有不准确,MySQL估计数据库中的作业数。 此数字可能会根据最近添加或删除的作业数量而波动。 对于不支持快速结果大小估计的其他数据库,将给出实际作业数。

对于开发者

代码维护

参见

Category:Job queue/zh#%20 Category:Installation/zh Category:MediaWiki concepts/zh
Category:Installation/zh Category:Job queue/zh Category:MediaWiki concepts/zh Category:Pages using deprecated NoteTA template