MemQ 实现异步任务

简介: 这几天在做推送相关的任务的时候发现了一段神奇的代码。$pushmsg = new NormalPushMsg($userid, $content, $clickurl,"");PushService::getInstance()->sendPushToMemq($pushmsg);一开始的时候我还纳闷,为什么不直接发呢,走这么大一圈子弯路到底是为了啥,后来想了想,发送push动辄几十上百万的用户,会是一个很耗时的操作。

"MemQ异步任务"

这几天在做推送相关的任务的时候发现了一段神奇的代码。

$pushmsg = new NormalPushMsg($userid, $content, $clickurl,"");
PushService::getInstance()->sendPushToMemq($pushmsg);

一开始的时候我还纳闷,为什么不直接发呢,走这么大一圈子弯路到底是为了啥,后来想了想,发送push动辄几十上百万的用户,会是一个很耗时的操作。短时间会对服务器造成不小的压力。而通过memq这样一种曲线救国的套路,倒也还是一个不错的方法。

下面就自己动手,也来实现一下这样的功能。

准备

总用量 16
-rw-r--r-- 1 root root  82 12月 19 14:15 config.ini
-rw-r--r-- 1 root root 339 12月 19 14:36 publish_tasks.php
-rw-r--r-- 1 root root 387 12月 19 14:38 runjobs_background.php
-rw-r--r-- 1 root root 176 12月 19 14:13 worker.php

config.ini

内容格式大概可以是下面的形式。

queuename = default
queueip = 192.168.1.1
queueport = 22201
classname = Worker

下面来讲讲每个参数对应的含义。
- queuename 是我们要进行存放的队列的名称
- queueip 即会在那台主机上执行对应的任务
- queueport 对应主机上memcache的端口
- classname 通过PHP的哪个类来执行对应的“异步”方法。

确切的来讲,对公司而言queueip和queueport是必须的,因为你会管理很多的主机,如果不进行限制,异步任务变多的时候,那就是一个灾难。但是对于本次试验而言,就没什么必要了。

worker.php

这个文件就是我们会具体调用的类文件,代码可以根据具体的业务需求而定。我这里只是演示一下,就随便写了。

<?php
class Worker {

    public function __construct() {
    }
    public function saveToLocal($msg="default data") {
        LiveLog("./worker.log", $msg);
    }
}

这个类的名称和上面的config.ini文件的classname保持一致就好了。否则会出现load错误的问题。

publish_tasks.php

按照一开始描述的,这个文件起到一个发布任务的作用。好比开启了一个给XXX用户群发送push召回的任务。这里还是简单的写一下。

<?php
header("Content-Type:text/html;charset=UTF-8");
require "/home/wwwroot/api.newtv.com/common/common.inc.php";

$memq = new useLiveMemQueue();
$key = "my:memq:test";
$msg = "哈哈哈哈哈啊哈哈哈,尴尬不?";
$result = $memq->cache($key, "saveToLocal('$msg')");
var_dump($result);

这里面有一些公司封装好的API,比如useLiveMemQueue类以及内部对应的cache方法。涉及到公司隐私性,就不再粘贴了。但是这都是对memcache的简单的封装,你自己花一点点时间也能写得出来的。

runjobs_background.php

任务已经被发布到了memq相应的队列中了,接下来就是要去消费它,否则很有可能导致服务器内存吃紧,那你的手机报警就哐哐的响了吧。

<?php
header("Content-Type:text/html;charset=UTF-8");
require "/home/wwwroot/api.newtv.com/common/common.inc.php";
require __DIR__."/worker.php";

$executor = null;
$memq = new useLiveMemQueue();
$method = trim($memq->get("my:memq:test"));
$classname = "Worker";
$executor = new $classname();

$execstr = "\$executor->$method".";";

$result = eval($execstr);
var_dump($result);

具体的原理,看完代码应该就明白了。其中最关键的就是PHP这门动态语言的优势。否则要使用Java这种编译性语言的话,还需要一套相应的反射机制了。

定时任务

一般来说,我们会写一个crontab脚本来定期的去“消费”memq中的“异步”任务,比如针对上面的实验,我们就可以写这样的一个crontab。

*/10 * * * * cd /home/wwwroot/workspace/mars/background/ && php runjobs_background.php 2>&1

每10分钟执行一次,相应的队列就会被消费掉了。但是这个10分钟只是一个频率。因为我们要进行消费的任务量会很大,10分钟内根本跑不完,在第二个10分钟的时候cron会再次开启一个进程,来进行消费。以此类推,就有可能会出现多个进程来消费相同的任务。

这个只要在不影响服务器性能的情况下,是没什么影响的,了解这么个情况就可以了。

验证结果

简单验证

好了,crontab部署后的10分钟已经到了,下面就来看看有没有生成
底层API
对应的worker.log文件吧。
成功生成了日志文件
“异步”运行结果

大规模测试

刚才只是在memq里面存放了一条“异步”任务,下面我们可以来试试多放点任务来试试。比如我们循环1000次cache操作,相当于在队列中存放了1000个待消费的任务。经过消费后,得到的结果如下。
查看worker.log结果

总结

到此,本次试验就结束了。相比较于自己随意的写代码,公司的代码库更具有实际意义,很多工程上的思维是学校的老师教不了的。多实践下,才能明白自身的不足之处。

这里使用的是PHP,所以在runjobs_background.php中执行起来才会很方便。如果使用其他的动态(解释性)语言,也会有如此感受。当然使用Java的话,就需要再写一个反射的工具类,多了一步,但也还是很方便的。

目录
相关文章
|
SQL 人工智能 数据挖掘
阿里云DMS,身边的智能化数据分析助手
生成式AI颠覆了人机交互的传统范式,赋予每个人利用AI进行低门槛数据分析的能力。Data Fabric与生成式AI的强强联合,不仅能够实现敏捷数据交付,还有效降低了数据分析门槛,让人人都能数据分析成为可能!阿里云DMS作为阿里云统一的用数平台,在2021年初就开始探索使用Data Fabric理念构建逻辑数仓来加速企业数据价值的交付,2023年推出基于大模型构建的Data Copilot,降低用数门槛,近期我们将Notebook(分析窗口)、逻辑数仓(Data Fabric)、Data Copilot(生成式AI)进行有机组合,端到端的解决用数难题,给用户带来全新的分析体验。
112901 120
阿里云DMS,身边的智能化数据分析助手
|
5月前
|
固态存储 关系型数据库 数据库
从Explain到执行:手把手优化PostgreSQL慢查询的5个关键步骤
本文深入探讨PostgreSQL查询优化的系统性方法,结合15年数据库优化经验,通过真实生产案例剖析慢查询问题。内容涵盖五大关键步骤:解读EXPLAIN计划、识别性能瓶颈、索引优化策略、查询重写与结构调整以及系统级优化配置。文章详细分析了慢查询对资源、硬件成本及业务的影响,并提供从诊断到根治的全流程解决方案。同时,介绍了索引类型选择、分区表设计、物化视图应用等高级技巧,帮助读者构建持续优化机制,显著提升数据库性能。最终总结出优化大师的思维框架,强调数据驱动决策与预防性优化文化,助力优雅设计取代复杂补救,实现数据库性能质的飞跃。
653 0
|
12月前
|
存储 数据安全/隐私保护
鸿蒙开发:自定义一个动态输入框
在鸿蒙开发中,如何实现这一效果呢,最重要的解决两个问题,第一个问题是,如何在上一个输入框输入完之后,焦点切换至下一个输入框中,第二个问题是,如何禁止已经输入的输入框的焦点,两个问题解决完之后,其他的就很是简单了。
161 13
鸿蒙开发:自定义一个动态输入框
|
12月前
|
存储 弹性计算 缓存
阿里云服务器通用型g8i实例性能与使用场景介绍及最新收费标准参考
阿里云ECS通用型g8i服务器采用阿里云全新CIPU架构,可提供稳定的算力输出、更强劲的I/O引擎以及芯片级的安全加固。ECS通用型g8i实例支持开启或关闭超线程配置,单台g8i实例最高支持100万IOPS。阿里云ECS通用型g8i实例CPU采用Intel®Xeon®Emerald Rapids或者Intel®Xeon®Sapphire Rapids,主频不低于2.7 GHz,全核睿频3.2GHz。本文为大家介绍通用型g8i实例性能与使用场景介绍及最新收费标准,以供参考。
|
SQL 关系型数据库 数据库
postgresql数据库修改参数的方式
在PostgreSQL数据库中,你可以通过多种方式修改数据库参数,以更改其行为。以下是一些常见的修改数据库参数的方式: 1. **通过配置文件修改(postgresql.conf):** PostgreSQL的配置文件是 `postgresql.conf`。你可以直接编辑该文件,找到要修改的参数,修改其值,然后重新启动PostgreSQL服务以使更改生效。 通常,`postgresql.conf` 文件位于 PostgreSQL 数据目录下。修改完毕后,确保重新启动 PostgreSQL 服务。 2. **使用 ALTER SYSTEM 命令:** PostgreSQL
888 2
|
SQL 关系型数据库 数据库
PostgreSQL 常用函数分享
PostgreSQL 常用函数分享
288 0
|
运维 监控 关系型数据库
【一文搞懂PGSQL】7. PostgreSQL + repmgr + witness 高可用架构
该文档介绍了如何构建基于PostgreSQL的高可用架构,利用repmgr进行集群管理和故障转移,并引入witness节点增强网络故障检测能力。repmgr是一款轻量级的开源工具,支持一键部署、自动故障转移及分布式节点管理。文档详细描述了环境搭建步骤,包括配置postgresql参数、安装与配置repmgr、注册集群节点以及配置witness节点等。此外,还提供了故障手动与自动切换的方法及常用命令,确保集群稳定运行。
|
机器学习/深度学习 存储 自然语言处理
XoT:一种新的大语言模型的提示技术
这是微软在11月最新发布的一篇论文,题为“Everything of Thoughts: Defying the Law of Penrose Triangle for Thought Generation”,介绍了一种名为XOT的提示技术,它增强了像GPT-3和GPT-4这样的大型语言模型(llm)解决复杂问题的潜力。
523 6
|
人工智能 BI 索引
小红的字符串构造和小红的排列构造
小红的字符串构造和小红的排列构造
155 1
|
小程序 前端开发 JavaScript
从零开始:小程序开发环境搭建详解
本文主要介绍了如何搭建小程序开发环境,并介绍了小程序开发的基本概念和开发流程。首先,文章介绍了小程序开发的基本要求和开发工具的安装方法,包括微信开发者工具和编辑器等。然后,文章通过实例介绍了小程序的基本结构和页面开发流程,并介绍了如何通过模板和组件开发加快开发速度。最后,文章介绍了如何通过调试和发布小程序来完成开发流程,同时给出了一些常见问题的解决方法。本文适合初学者了解小程序开发的基础知识和开发流程,帮助读者更快速地上手小程序开发。
930 0
从零开始:小程序开发环境搭建详解
下一篇
开通oss服务