Yii2 队列扩展,Redis 驱动中,info 命令打印关于队列状态的信息时,reserved 状态的队列的删除
1、查看 log 表,其 message 字段内容如下:
yii\web\NotFoundHttpException: The task ID of the channel's article: 2209, does not exist in /mcloud/www/channel-pub-api/common/components/queue/PubArticleEventHandler.php:93 Stack trace: #0 [internal function]: common\components\queue\PubArticleEventHandler::afterError(Object(yii\queue\ErrorEvent)) #1 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/base/Component.php(627): call_user_func(Array, Object(yii\queue\ErrorEvent)) #2 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/Queue.php(246): yii\base\Component->trigger('afterError', Object(yii\queue\ErrorEvent)) #3 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/cli/Command.php(198): yii\queue\Queue->handleError('159', Object(wx\jobs\PubArticleJob), '300', '1085', Object(Symfony\Component\Process\Exception\ProcessFailedException)) #4 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/cli/Command.php(125): yii\queue\cli\Command->handleMessage('159', 'O:21:"wx\\jobs\\P...', '300', '1085') #5 [internal function]: yii\queue\cli\Command->yii\queue\cli\{closure}('159', 'O:21:"wx\\jobs\\P...', '300', '1085') #6 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/cli/Queue.php(144): call_user_func(Object(Closure), '159', 'O:21:"wx\\jobs\\P...', '300', '1085') #7 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/drivers/redis/Queue.php(61): yii\queue\cli\Queue->handleMessage('159', 'O:21:"wx\\jobs\\P...', '300', '1085') #8 [internal function]: yii\queue\redis\Queue->yii\queue\redis\{closure}(Object(Closure)) #9 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/cli/Queue.php(117): call_user_func(Object(Closure), Object(Closure)) #10 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/drivers/redis/Queue.php(68): yii\queue\cli\Queue->runWorker(Object(Closure)) #11 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2-queue/src/drivers/redis/Command.php(76): yii\queue\redis\Queue->run(true, 3) #12 [internal function]: yii\queue\redis\Command->actionListen(3) #13 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array) #14 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array) #15 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/console/Controller.php(148): yii\base\Controller->runAction('listen', Array) #16 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/base/Module.php(528): yii\console\Controller->runAction('listen', Array) #17 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/console/Application.php(180): yii\base\Module->runAction('pub-article-que...', Array) #18 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/console/Application.php(147): yii\console\Application->runAction('pub-article-que...', Array) #19 /mcloud/www/channel-pub-api/vendor/yiisoft/yii2/base/Application.php(386): yii\console\Application->handleRequest(Object(yii\console\Request)) #20 /mcloud/www/channel-pub-api/yii(23): yii\base\Application->run() #21 {main}
2、分析发现,发布文章队列事件处理器,发布文章队列的作业执行失败后,common\components\queue\PubArticleEventHandler::afterError(ExecEvent $event),在此方法中抛出异常,一旦抛出异常,进而便会导致此发布文章队列的状态一直处于:reserved,因此,应该尽可能避免在此方法中抛出异常
<?php /** * Created by PhpStorm. * User: Qiang Wang * Date: 2018/10/23 * Time: 19:36 */ namespace common\components\queue; use Yii; use common\services\TaskService; use common\services\ChannelAppTaskService; use common\services\ArticleTypeService; use yii\base\Component; use yii\queue\ExecEvent; use yii\web\NotFoundHttpException; use yii\web\UnprocessableEntityHttpException; /** * Class PubArticleEventHandler * @package common\components\queue * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class PubArticleEventHandler extends Component { /** * @param ExecEvent $event * @throws NotFoundHttpException 如果未找到数据模型,将抛出 404 HTTP 异常 * @throws UnprocessableEntityHttpException 如果找到数据模型,状态未启用,将抛出 422 HTTP 异常 */ public static function afterExec(ExecEvent $event) { $channelAppTaskId = $event->job->channelAppTaskId; // 基于ID查找状态为未禁用的单个数据模型(渠道的应用的任务) $channelAppTaskDisabledNoItem = ChannelAppTaskService::findModelDisabledNoById($channelAppTaskId); // 基于ID查找状态为启用的单个数据模型(任务) $taskEnabledItem = TaskService::findModelEnabledById($channelAppTaskDisabledNoItem->task_id); $serviceClass = 'common\services\\' . str_replace(' ', '', ucwords(str_replace('_', ' ', $taskEnabledItem->channel_type_code))) . 'ArticleService'; // 例:common\services\QqCwArticleService $articleModel = 'common\logics\\' . str_replace(' ', '', ucwords(str_replace('_', ' ', $taskEnabledItem->channel_code))) . 'Article'; // 例:common\logics\QqArticle // 基于任务ID查找单个数据模型(渠道的文章) $articleModelItem = $articleModel::find()->where(['task_id' => $taskEnabledItem->id])->isDeletedNo()->one(); // 如果未找到数据模型,将抛出 404 HTTP 异常 if (!isset($articleModelItem)) { throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202091'), ['task_id' => $taskEnabledItem->id])), 202091); } /* 判断状态,如果未启用,将抛出 422 HTTP 异常 */ if ($articleModelItem->status !== $articleModelItem::STATUS_ENABLED) { throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202092'), ['task_id' => $taskEnabledItem->id])), 202092); } // 基于ID查找状态为启用的单个数据模型(文章类型) $articleTypeEnabledItem = ArticleTypeService::findModelEnabledById($articleModelItem->article_type_id); $serviceAction = 'pubArticle' . str_replace(' ', '', ucwords(str_replace('_', ' ', $articleTypeEnabledItem->code))) . 'ExecHandler'; // 例:pubArticleVideoExecHandler $serviceClass::$serviceAction($channelAppTaskId); } /** * @param ExecEvent $event * @throws NotFoundHttpException 如果未找到数据模型,将抛出 404 HTTP 异常 * @throws UnprocessableEntityHttpException 如果找到数据模型,状态未启用,将抛出 422 HTTP 异常 */ public static function afterError(ExecEvent $event) { $channelAppTaskId = $event->job->channelAppTaskId; // 基于ID查找状态为未禁用的单个数据模型(渠道的应用的任务) $channelAppTaskDisabledNoItem = ChannelAppTaskService::findModelDisabledNoById($channelAppTaskId); // 基于ID查找状态为启用的单个数据模型(任务) $taskEnabledItem = TaskService::findModelEnabledById($channelAppTaskDisabledNoItem->task_id); $serviceClass = 'common\services\\' . str_replace(' ', '', ucwords(str_replace('_', ' ', $taskEnabledItem->channel_type_code))) . 'ArticleService'; // 例:common\services\QqCwArticleService $articleModel = 'common\logics\\' . str_replace(' ', '', ucwords(str_replace('_', ' ', $taskEnabledItem->channel_code))) . 'Article'; // 例:common\logics\QqArticle // 基于任务ID查找单个数据模型(渠道的文章) $articleModelItem = $articleModel::find()->where(['task_id' => $taskEnabledItem->id])->isDeletedNo()->one(); // 如果未找到数据模型,将抛出 404 HTTP 异常 if (!isset($articleModelItem)) { throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202091'), ['task_id' => $taskEnabledItem->id])), 202091); } /* 判断状态,如果未启用,将抛出 422 HTTP 异常 */ if ($articleModelItem->status !== $articleModelItem::STATUS_ENABLED) { throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '202092'), ['task_id' => $taskEnabledItem->id])), 202092); } // 基于ID查找状态为启用的单个数据模型(文章类型) $articleTypeEnabledItem = ArticleTypeService::findModelEnabledById($articleModelItem->article_type_id); $serviceAction = 'pubArticle' . str_replace(' ', '', ucwords(str_replace('_', ' ', $articleTypeEnabledItem->code))) . 'ErrorHandler'; // 例:pubArticleVideoErrorHandler $serviceClass::$serviceAction($channelAppTaskId, $event->error); } }
3、Yii2 队列扩展,Redis 驱动中,info 命令打印关于队列状态的信息时,reserved 状态的队列数量为 33,如图1
[root@cc121bb54862 /]# cd /mcloud/www/channel-pub-api/ [root@cc121bb54862 channel-pub-api]# ./yii copy-asset-queue/info --color=0 Jobs - waiting: 0 - delayed: 0 - reserved: 0 - done: 146 [root@cc121bb54862 channel-pub-api]# ./yii upload-asset-queue/info --color=0 Jobs - waiting: 0 - delayed: 0 - reserved: 0 - done: 0 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 20 - delayed: 0 - reserved: 33 - done: 162 [root@cc121bb54862 channel-pub-api]# ./yii source-callback-queue/info --color=0 Jobs - waiting: 0 - delayed: 0 - reserved: 0 - done: 166
4、由于 Supervisor 仅启动 1 个 queue/listen,因此,一旦某一队列处于 reserved,则其他队列只好一直处于 waiting 状态,所以,临时决定 remove 命令删除作业,以启动程序的继续正常运转,查看 log 表,其 message 字段内容,可以确定队列 ID 值为:159,info 命令打印关于队列状态的信息时,reserved 状态的队列数量减少 1,done 状态的队列数量增加 1,符合预期,如图2
[root@cc121bb54862 /]# cd /mcloud/www/channel-pub-api/ [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 20 - delayed: 0 - reserved: 33 - done: 162 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/remove 159 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 20 - delayed: 0 - reserved: 32 - done: 163
5、基于以上流程,重复地分别执行 remove 命令删除作业,等待一段时间后,info 命令打印关于队列状态的信息时,reserved 状态的队列数量持续减少中,done 状态的队列数量持续增加中,符合预期
[root@cc121bb54862 /]# cd /mcloud/www/channel-pub-api/ [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 18 - delayed: 0 - reserved: 33 - done: 164 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/remove 184 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 17 - delayed: 0 - reserved: 33 - done: 165 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/remove 175 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 18 - delayed: 0 - reserved: 30 - done: 167 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/remove 141 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 18 - delayed: 0 - reserved: 29 - done: 168 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/remove 168 [root@cc121bb54862 channel-pub-api]# ./yii pub-article-queue/info --color=0 Jobs - waiting: 17 - delayed: 0 - reserved: 29 - done: 169
近期评论