1. Check the log table; its message field contains the following:
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. Analysis reveals that in the event handler for the publish article queue, after the job execution for the publish article queue fails, common\components\queue\PubArticleEventHandler::afterError(ExecEvent $event) throws an exception. Once an exception is thrown, it causes the status of this publish article queue to remain as: reserved. Therefore, you should avoid throwing exceptions in this method whenever possible.
<?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. In the Yii2 queue extension with the Redis driver, when the info command prints information about the queue status, the number of queues in the reserved state is 33, as shown in Figure 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. Because Supervisor starts only 1 queue/listen, once a queue is in the reserved state, all other queues must remain in the waiting state. Therefore, I temporarily decided to use the remove command to delete the job in order to resume normal program operation. Checking the message field in the log table confirms the queue ID value is: 159. When the info command prints the queue status information, the number of queues in the reserved state decreases by 1, and the number of queues in the done state increases by 1, as expected, as shown in Figure 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. Based on the above process, I repeatedly executed the remove command to delete jobs. After waiting for a while, when the info command prints the queue status information, the number of queues in the reserved state continues to decrease, and the number of queues in the done state continues to increase, as expected.
[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
