Hyperf结合Redis异步队列任务async-queue实现后台操作日志写入

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: Hyperf结合Redis异步队列任务async-queue实现后台操作日志写入
本文环境 Hyperf2.1,PHP7.3,Mysql5.7\
不懂的可以评论或联系我邮箱:owen@owenzhang.com\
著作权归OwenZhang所有。商业转载请联系OwenZhang获得授权,非商业转载请注明出处。

业务场景介绍

前天接到一个需求,后台管理系统,记录后台账号的操作记录信息。

由于是集团后台,这样操作者就很多,但操作日志却是很关键的信息,必须得写入数据库,这样多用户写入,我们就得用到异步队列进行消费,防止写入失败,如果队列进行消费指定参数后还是失败,就得写入日志进行钉钉消息推送,具体可以看我另外一篇文章:

lite-monitor 一款基于 shell 命令的监控系统 - owenzhang24的个人空间 - OSCHINA - 中文开源技术交流社区

需求产品原型图:

image.png

Hyperf & async-queue介绍

Hyperf 介绍

Hyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换 与 可复用 的。

async-queue 介绍

async-queue是Redis 异步队列,异步队列区别于 RabbitMQ Kafka 等消息队列,它只提供一种 异步处理 和 异步延时处理 的能力,并 不能 严格地保证消息的持久化和 不支持 ACK 应答机制。

官方文档:
Redis 异步队列 (hyperf.wiki)

async-queue 安装

使用composer将 async-queue 安装到你的项目中:

composer require hyperf/async-queue

插件环境要求:
image.png
参考Packagist:
hyperf/async-queue - Packagist

async-queue 配置

配置文件位于 config/autoload/async_queue.php,如文件不存在可自行创建。

我的项目配置如下:

<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
return [
    'default' => [
        'driver' => Hyperf\AsyncQueue\Driver\RedisDriver::class,
        'channel' => 'plan_queue',//队列前缀
        'timeout' => 5,//pop 消息的超时时间
        'retry_seconds' => 5,//失败后重新尝试间隔
        'handle_timeout' => 5,//消息处理超时时间
        'processes' => 5, //增加异步队列进程数量,加快消费速度
    ],
];

其他配置可以参考官方文档

微信截图_20220120161605.png

代码实例

消费队列接口类

函数说明:

  • __construct() 任务执行失败后的重试次数,即最大执行次数为 $maxAttempts+1 次
  • handle() 执行任务日志写入数据库

代码实例:

<?php

declare(strict_types=1);

namespace App\Job;

use App\Model\HoutaiOperationLog;
use Hyperf\AsyncQueue\Job;
use Hyperf\Utils\ApplicationContext;

class OperationLogAddJob extends Job
{
    public $params;

    /**
     * 任务执行失败后的重试次数,即最大执行次数为 $maxAttempts+1 次
     *
     * @var int
     */
    protected $maxAttempts = 0;

    public function __construct($params)
    {
        $this->params = $params;
    }

    /**
     * 执行任务 日志写入数据库
     * @var int
     */
    public function handle()
    {
        $container = ApplicationContext::getContainer();
        $logger = $container->get(\Hyperf\Logger\LoggerFactory::class)->get('log', 'default');

        try {
            $insertData = [
                'operation_type' => $this->params['operation_type'],
                'operation_page' => $this->params['operation_page'],
                'content' => $this->params['content'],
                'status' => $this->params['status'],
                'ip' => $this->params['ip'],
                'created_id' => $this->params['created_id'],
                'app' => $this->params['app'],
                'created_at' => date('Y-m-d H:i:s'),
            ];

            return HoutaiOperationLog::query()->insert($insertData);
        } catch (\Exception $e) {
            $logger->error('后台操作日志添加失败:' . $e->getMessage());
        }

        return 'success';
    }
}

写入异步队列函数方法

操作日志添加队列函数方法

代码实例:

/**
 * Describe: 个人中心-操作日志添加队列
 * Route: get /admin/operation_log_list
 * @param int $operationType 操作类型,1登录,2登出,3编辑修改,4新增创建,5删除,6导出数据,7导入数据(导出和导入暂时不做)
 * @param string $operationPage 操作页面
 * @param string $content 操作内容
 * @param int $status 操作状态,1成功,2失败
 * Created by OwenZhang at 2022/01/17 10:14
 */
public function operationLogAdd(int $operationType, string $operationPage, string $content, int $status)
{
    try {
        $driverFactory = ApplicationContext::getContainer()->get(DriverFactory::class);
        $driver = $driverFactory->get('default');

        $params['operation_type'] = $operationType;
        $params['operation_page'] = $operationPage;
        $params['content'] = $content;
        $params['status'] = $status;
        $params['ip'] = Context::get('ip') ?? '';
        $params['created_id'] = Context::get('system_user_id') ?? 0;
        $params['app'] = Context::get('app') ?? 0;

        return $driver->push(new OperationLogAddJob($params));
    } catch (\Exception $e) {
        throw new BusinessException(9999, '操作日志添加失败:' . $e->getMessage());
    }
}

调用写入异步队列函数方法

具体业务类下写入

代码实例:

$this->operationLogService->operationLogAdd(operationLogService::TYPE_EDIT, '运营管理&配置-意见反馈', "【意见反馈】【{$statusName}】【ID{$ids}】", operationLogService::STATUS_SUCCESS);

Buy me a cup of coffee :)

觉得对你有帮助,就给我打赏吧,谢谢!

Buy me a cup of coffee :)

https://www.owenzhang.com/wechat_reward.png

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
SQL Java Serverless
实时计算 Flink版操作报错合集之在写入SLS(Serverless Log Service)时出现报错,该如何排查
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
1天前
|
运维 DataWorks 安全
DataWorks产品使用合集之任务日志中显示等待gateway调度资源,该如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
1天前
|
数据采集 DataWorks 监控
DataWorks产品使用合集之数据集成任务日志中显示wait,是什么原因
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
5天前
|
Java 编译器 数据库
异步日志方案——spdlog
异步日志方案——spdlog
|
21天前
|
Java Serverless 应用服务中间件
函数计算操作报错合集之JVM启动时找不到指定的日志目录,该如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
22天前
|
监控 数据管理 关系型数据库
数据管理DMS使用问题之是否支持将操作日志导出至阿里云日志服务(SLS)
阿里云数据管理DMS提供了全面的数据管理、数据库运维、数据安全、数据迁移与同步等功能,助力企业高效、安全地进行数据库管理和运维工作。以下是DMS产品使用合集的详细介绍。
|
26天前
|
NoSQL Linux Redis
Redis性能优化问题之想确认Redis延迟变大是否因为fork耗时导致的,如何解决
Redis性能优化问题之想确认Redis延迟变大是否因为fork耗时导致的,如何解决
|
26天前
|
存储 缓存 NoSQL
Redis性能优化问题之优化 Redis fork 耗时严重的问题,如何解决
Redis性能优化问题之优化 Redis fork 耗时严重的问题,如何解决
|
6天前
|
消息中间件 Java 调度
"解锁RabbitMQ云版:揭秘电商巨头、日志大师、任务狂人的秘密武器,你的系统升级就差这一步!"
【8月更文挑战第14天】在分布式与微服务架构中,RabbitMQ云版本作为消息队列服务,助力系统间解耦与异步通信。通过三个场景展示其实用性:1) 订单处理系统中,利用RabbitMQ实现跨服务流程的解耦;2) 日志收集与分析,异步发送日志至中央系统,保障业务流畅;3) 任务调度,处理耗时任务避免阻塞主线程。这些应用充分展现了RabbitMQ云版本的强大功能和灵活性。
16 0
|
1月前
|
数据采集 分布式计算 DataWorks
DataWorks产品使用合集之任务工作流中遇到了日志信息显示参数值没有正确解析的问题,该如何处理
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。