惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
V2EX - 技术
V2EX - 技术
T
Troy Hunt's Blog
TaoSecurity Blog
TaoSecurity Blog
Attack and Defense Labs
Attack and Defense Labs
SecWiki News
SecWiki News
M
MIT News - Artificial intelligence
N
News and Events Feed by Topic
Help Net Security
Help Net Security
IT之家
IT之家
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
The Last Watchdog
The Last Watchdog
Martin Fowler
Martin Fowler
Hacker News: Ask HN
Hacker News: Ask HN
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理
H
Heimdal Security Blog
B
Blog
Blog — PlanetScale
Blog — PlanetScale
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
I
InfoQ
腾讯CDC
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Know Your Adversary
Know Your Adversary
Cloudbric
Cloudbric
Project Zero
Project Zero
T
Tor Project blog
小众软件
小众软件
博客园 - 司徒正美
www.infosecurity-magazine.com
www.infosecurity-magazine.com
H
Help Net Security
Webroot Blog
Webroot Blog
量子位
NISL@THU
NISL@THU
Schneier on Security
Schneier on Security
Google Online Security Blog
Google Online Security Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
月光博客
月光博客
宝玉的分享
宝玉的分享
V
V2EX
T
Tailwind CSS Blog
Spread Privacy
Spread Privacy
G
Google Developers Blog
K
Kaspersky official blog

PHP武器库

4天花40亿,glm-5v-turbo体验笔记-PHP武器库 ulthon_admin 2.1 全面支持智能体驱动,内置框架技能,自动建表、自动分配菜单、自动分配权限、页面接口同体、自动验证接口和数据!-PHP武器库 CSS框架的“最后一公里”:从基础元件到业务场景-PHP武器库 ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架-PHP武器库 Caddy 流量监控终极指南:用 Prometheus + Grafana 点亮你的服务黑盒-PHP武器库 从零到一:用 Vue 打造一个零依赖、插件化的 JS 库-PHP武器库 告别PECL,拥抱PIE:像Composer一样管理PHP扩展-PHP武器库 大规模 PHP 应用在高并发下如何进行性能优化?-PHP武器库 HTTPS 自签名证书生成与安装完整指南-PHP武器库 BTRFS 核心功能与实践笔记-PHP武器库 一个社区语言能泛起多大浪花?PHP30周年线上活动PHPverse-PHP武器库 盘点一下这些年PHP在桌面应用方面的解决方案-PHP武器库 ulthon_admin 发布新版,新增地图选点组件、优化提示样式、增强优化多出细节-PHP武器库 像树一样,慢慢生长!包含大量特性更新,升级底层layui和ThinkPHP、增加docker配置、升级权限配置、更换富文本、实现新的扩展架构和代码架构等等。-PHP武器库 PHP网站改版了知道吗?-PHP武器库 BSD 开源协议解析:自由度与灵活性的平衡-PHP武器库 感觉PHP和vue在前端方面差不多,有没有必要学vue或者其他的前端框架?-PHP武器库 前端会被后端代替吗?-PHP武器库 有哪些知名的网站使用 PHP 进行开发?-PHP武器库 想学编程,java,python,php先学哪个比较好?-PHP武器库 现在的 ThinkPHP8(重构版) 和 Laravel8哪个好? -PHP武器库 PHP8.3发布-PHP武器库 [AppNode]Linux 服务器集群管理面板-PHP武器库 [Hestia]开源网络服务器控制面板,快速、可靠、开源-PHP武器库 web初学者如何保证自身服务器安全?-PHP武器库
PHP 高性能队列探索:从 SQLite 到内存,我们该如何选择?-PHP武器库
2025-09-29 · via PHP武器库

在现代 PHP 应用开发中,将耗时任务(如邮件发送、报表生成、数据同步)从主请求流程中剥离出来进行异步处理,是提升用户体验和系统吞吐量的关键。虽然 RabbitMQ、Kafka 等专业消息队列是标准解决方案,但对于中小型项目或追求轻量级架构的场景,我们往往希望找到一个更“接地气”的方案。

本文记录了一次完整的技术探索之旅:从一个简单的想法开始,如何利用 PHP 生态中已有的工具,构建一个能够应对“大量写入、少量消费”场景的高性能队列。

需求起点:一个轻量级的任务队列

我们的核心需求很简单:
1.  轻量级:不希望引入新的、重型的服务依赖(如 Java/Erlang 系的消息中间件)。
2.  可靠:任务不能轻易丢失。
3.  高性能:能够承受 Web 应用在高并发下的大量任务写入。

很自然地,我们的第一个想法落在了 SQLite 身上。它无需额外服务、零配置、就是一个文件,完美符合“轻量级”的要求。

还有一个需求,这个针对的是单机内部的队列,比如日志记录,日志先记录到队列中,再通过消费者统一记录到集中机器上。

思路一:SQLite 作为队列的初步尝试与瓶颈

使用 SQLite 做队列的思路非常直接:生产者 (PHP-FPM) 在 Web 请求中向 tasksINSERT 一条记录;消费者 (CLI) 则是一个后台脚本,循环 SELECT 任务来处理。

版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。

然而,当面临“大量写入、少量消费”的场景时,瓶颈很快出现:写入并发。SQLite 在默认模式下,任何时刻只允许一个写入者。当成百上千个 PHP-FPM 进程同时尝试插入任务时,会激烈地争夺数据库的写锁,导致大量请求失败或超时。

基础优化

为了解决并发问题,一些基础优化是必须的:
1.  开启 WAL 模式PRAGMA journal_mode=WAL;,允许一个写入者和多个读取者并发,极大缓解了锁争用。
2.  设置超时PRAGMA busy_timeout = 5000;,让写入失败的进程等待一段时间而不是立即报错。
3.  使用高速磁盘 (SSD):从物理层面提升 I/O 性能。

这些优化能解决大部分问题,但如果写入压力达到极限,我们还能做什么?

思路二:探索纯内存方案

为了彻底消除磁盘 I/O 瓶颈,我们自然想到了内存。

方案 A:APCu - 一个美丽的陷阱

APCu 是 PHP 的一个共享内存缓存。我们可以用一个共享数组来当队列。但这很快暴露了新问题:

CPU 争用:为了保证并发安全,我们必须使用 apcu_cas (Compare-And-Swap) 循环来写入。在高并发下,大量进程会在此处“忙等待” (Busy-Waiting),疯狂空转 CPU,导致系统负载飙升。  

版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。

数据易失:服务重启,内存中的所有任务全部丢失。

结论:APCu 方案在高并发写入下性能不佳且有数据丢失风险,不推荐。

方案 B:Redis - 专业选手,但增加了依赖

Redis 是内存方案的工业标准。它使用高效的事件循环模型,提供原子的列表操作 (LPUSH/BRPOP),性能卓越且功能丰富。它也支持数据持久化。唯一的“缺点”是,它违背了我们最初“不引入新服务”的原则。

思路三:两全其美?SQLite on tmpfs

有没有一种方案,既能拥有内存的极致速度,又能利用 SQLite 成熟的并发模型,还无需修改代码?答案是:将 SQLite 数据库文件放在内存文件系统 (tmpfs) 中

在 Linux 中,tmpfs 是一个基于内存的文件系统(/dev/shm 就是一个现成的例子)。我们可以将 SQLite 数据库文件创建在这里。

优点

  1. 极致性能:所有数据库操作,包括加锁、读写,都变成了内存操作,速度极快。
  2. 健壮的并发模型:我们依然享受着 SQLite 优秀的“阻塞等待”并发模型,没有 APCu 的 CPU 空转问题。
  3. 零代码修改:PHP 代码无需任何改动,只需改变数据库文件的路径。

缺点

  • 数据完全易失:和所有内存方案一样,服务器重启,数据灰飞烟灭。这个方案非常适合任务可再生的场景(如生成缩略图、更新缓存),但不适用于关键业务(如订单处理)。

最终方案:在 Docker 中优雅地实现 "SQLite on tmpfs"

在现代化的 Docker 开发环境中,实现这个方案变得异常简单和优雅。我们无需手动在服务器上执行 mount 命令,只需在 docker-compose.yml 中声明即可。

版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。

# File: docker-compose.yml
version: '3.8'

services:
  php-fpm:
    build: ./php
    volumes:
      - ./src:/app
    # 关键配置:声明一个 tmpfs 挂载
    tmpfs:
      # 推荐方案:精确设置所有者
      - /app/ramdisk:size=256M,uid=33,gid=33

  # ... 其他服务

权限设置:专业做法 vs. 粗暴捷径

由于 PHP-FPM 进程通常以低权限用户(如 www-data)运行,而 tmpfs 默认由 root 创建,直接写入会因权限不足而失败。

专业做法(推荐):通过 uid=33,gid=33(www-data 的典型 ID),我们精确地将内存目录的所有权交给了 PHP 进程,这遵循了安全的最小权限原则。    

粗暴捷径(不推荐):使用 mode=0777。这会将目录权限设为 rwxrwxrwx,允许容器内的任何用户写入。虽然能解决问题,但它过度授权,留下了安全隐患。

总结

由此来看,如果我们不通过Redis或其他专业的消息队列服务,同时要处理的任务是在单机内的,不需要远程互联,那么我们完全可以通过sqlite实现,再配合linux开启内存文件系统,避免触发磁盘IO。虽然无论从写入、更新、删除、读取等任何方面,Redis都更专业,性能更好,但我们的方案是更简单的,同时可以利用sql表结构,很省事的实现队列的需求。

原文标题: PHP 高性能队列探索:从 SQLite 到内存,我们该如何选择?

原文地址: https://phpreturn.com/index/a68d9e185d81e3.html

原文平台: PHP武器库

版权声明: 本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。