Jerry's WIKIJerry's WIKI
概述
  • 🐞 web使用
  • 📐 常用组件
  • 💡 使用技巧
  • 🎱 规范相关
  • 🖥 工作流
  • 🛠 常用工具
  • 🌐️ 服务器
  • 📦 容器相关
  • ♨️ 编程语言
咖啡屋
  • 简体中文
  • English
GitHub
概述
  • 🐞 web使用
  • 📐 常用组件
  • 💡 使用技巧
  • 🎱 规范相关
  • 🖥 工作流
  • 🛠 常用工具
  • 🌐️ 服务器
  • 📦 容器相关
  • ♨️ 编程语言
咖啡屋
  • 简体中文
  • English
GitHub
  • 📞 事件机制

    • 事件角色和注意事项
    • 代码示例
  • ⏰ 定时任务
  • ⛓ 自定义进程
  • 📝 文件系统
  • 🕓 缓存系统
  • 📩 异步队列

    • 队列使用
    • 注意事项
  • 🚦 信号处理器
  • 📤 GuzzleHttp
  • 📉 限流器
  • ❌ 异常处理器
  • 🖨 日志
  • 📡 命令行
  • 🔁 WebSocket

命令行

目录

  • 执行定时任务开关
  • 队列投递开关
  • 维护模式
    • 命令行代码
    • 中间件代码

【注意】

这里列举了我增加的一些命令行,关于使用,请参考文档:命令行

执行定时任务开关

【说明】

通过改变外部变量,从而实现是否跳过定时任务的消费逻辑,打个比方:发动机在运转,但是没有挂挡。
执行进程会按照规则执行该任务,但是任务会优先判断外部变量,从而判断是否要执行定时任务。

命令:

php bin/hyperf crontab:switch start|stop

查看代码
<?php

declare(strict_types=1);

namespace App\Command;

use App\Constants\ConstCode;
use Hyperf\Cache\Cache;
use Hyperf\Command\Annotation\Command;
use Hyperf\Command\Command as HyperfCommand;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Throwable;

#[Command]
class SchedulerCommand extends HyperfCommand
{
    protected const START = 'start';

    protected const STOP = 'stop';

    public function __construct(protected ContainerInterface $container)
    {
        parent::__construct('crontab:switch');
    }

    public function configure()
    {
        parent::configure();
        $this->setHelp('make scheduler running logic or not. eg: php bin/hyperf crontab:switch start');
        $this->setDescription('定时任务是否执行消费逻辑');
        $this->addArgument('action', InputArgument::REQUIRED, 'start or stop');
    }

    public function handle()
    {
        $argumentAction = $this->input->getArgument('action');
        try {
            $cache = $this->container->get(Cache::class);
            if ($argumentAction === self::STOP) {
                $cache->delete(ConstCode::SCHEDULER_IS_RUNNING_KEY);
                $this->line('定时任务已跳出执行逻辑', 'info');
            } else {
                $cache->set(ConstCode::SCHEDULER_IS_RUNNING_KEY, 'SCHEDULER-IS-NOT-RUNNING');
                $this->line('定时任务已进入执行逻辑', 'info');
            }
        } catch (Throwable $e) {
            $this->line('发生错误: ' . $e->getMessage(), 'error');
        }
    }
}


队列投递开关

【说明】

通过改变外部变量,从而实现是否投递Redis队列任务。

命令:

php bin/hyperf queue:switch ${QUEUE_NAME} start|stop

查看代码
<?php

declare(strict_types=1);

namespace App\Command;

use App\Lib\RedisQueue\RedisQueueFactory;
use Hyperf\Cache\Cache;
use Hyperf\Command\Annotation\Command;
use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Contract\ConfigInterface;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Throwable;

/**
 * 是否允许业务向redis异步队列投递消息.
 * Class QueuePushCommand.
 */
#[Command]
class QueuePushCommand extends HyperfCommand
{
    protected const START = 'start';

    protected const STOP = 'stop';

    public function __construct(protected ContainerInterface $container)
    {
        parent::__construct('queue:switch');
    }

    public function configure()
    {
        parent::configure();
        $this->setHelp('allow or forbid push message to redis queue. eg: php bin/hyperf queue:switch redis-queue start');
        $this->setDescription('允许或禁止向指定的队列投递信息');
        $this->addArgument('queue_name', InputArgument::REQUIRED, 'redis queue name');
        $this->addArgument('action', InputArgument::OPTIONAL, 'start or stop', 'start');
    }

    public function handle()
    {
        [$argumentQueueName, $argumentAction] = [
            $this->input->getArgument('queue_name'),
            $this->input->getArgument('action'),
        ];
        try {
            [$config, $cache] = [
                $this->container->get(ConfigInterface::class),
                $this->container->get(Cache::class),
            ];
            $allRedisQueueName = array_keys($config->get('async_queue'));
            if (! in_array($argumentQueueName, $allRedisQueueName)) {
                $this->line($argumentQueueName . ' 队列未配置, 请检查', 'error');
                return null;
            }
            if (! in_array($argumentAction, ['stop', 'start'])) {
                $this->line('action 只允许 start 或 stop', 'error');
                return null;
            }

            $key = sprintf(RedisQueueFactory::IS_PUSH_KEY, $argumentQueueName);
            if ($argumentAction === self::START) {
                $cache->set($key, "{$argumentQueueName}:{$argumentAction}");
                $this->line("{$argumentQueueName} 队列已允许投递消息 !!!", 'info');
            } else {
                $cache->delete($key);
                $this->line("{$argumentQueueName} 队列已禁止投递消息 !!!", 'info');
            }
        } catch (Throwable $e) {
            $this->line('发生异常: ' . $e->getMessage(), 'error');
        }
    }
}


维护模式

【注意】

命令行用于修改外部变量,中间件判断该变量是否处于维护模式。


命令行代码

查看代码
<?php

declare(strict_types=1);

namespace App\Command;

use App\Constants\ConstCode;
use Hyperf\Cache\Cache;
use Hyperf\Command\Annotation\Command;
use Hyperf\Command\Command as HyperfCommand;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Throwable;

#[Command]
class FixModeCommand extends HyperfCommand
{
    protected const START = 'start';

    protected const STOP = 'stop';

    public function __construct(protected ContainerInterface $container)
    {
        parent::__construct('website:switch');
    }

    public function configure()
    {
        parent::configure();
        $this->setHelp('make website to fix mode. eg: php bin/hyperf website:switch start');
        $this->setDescription('网站是否进入维护模式');
        $this->addArgument('action', InputArgument::REQUIRED, 'start or stop');
    }

    public function handle()
    {
        $argumentAction = $this->input->getArgument('action');
        try {
            $cache = $this->container->get(Cache::class);
            if ($argumentAction === self::STOP) {
                $cache->set(ConstCode::FIX_MODE, 'WEBSITE-IS-IN-FIX-MODE');
                $this->line('网站已进入维护模式', 'info');
            } else {
                $cache->delete(ConstCode::FIX_MODE);
                $this->line('网站已脱离维护模式', 'info');
            }
        } catch (Throwable $e) {
            $this->line('发生错误: ' . $e->getMessage(), 'error');
        }
    }
}


中间件代码

详情
<?php

declare(strict_types=1);

namespace App\Middleware;

// 进入维护模式时, 所有的请求均不可访问
use App\Constants\ConstCode;
use App\Constants\SystemCode;
use Hyperf\Cache\Cache;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\SimpleCache\InvalidArgumentException;

class MaintenanceMiddleware extends AbstractMiddleware
{
    /**
     * 是否开启维护模式.
     * @param ServerRequestInterface $request 请求类
     * @param RequestHandlerInterface $handler 处理器
     * @return ResponseInterface 响应
     * @throws ContainerExceptionInterface 异常
     * @throws NotFoundExceptionInterface 异常
     * @throws InvalidArgumentException 异常
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $cache = $this->container->get(Cache::class);
        $isFixMode = $cache->get(ConstCode::FIX_MODE, false);
        if ($isFixMode !== false) {
            return $this->buildErrorResponse(SystemCode::FIX_MODE);
        }
        return $handler->handle($request);
    }
}

编辑此页面
更新时间:
贡献者: 田朝帆
Prev
日志
Next
Websocket使用