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

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hugging Face - Blog
Hugging Face - Blog
F
Fortinet All Blogs
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX
Y
Y Combinator Blog
博客园_首页
Martin Fowler
Martin Fowler
博客园 - 司徒正美
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
B
Blog
有赞技术团队
有赞技术团队
A
About on SuperTechFans
量子位
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
M
MIT News - Artificial intelligence
阮一峰的网络日志
阮一峰的网络日志
Jina AI
Jina AI

博客园 - MK2

cnpmcore 超大 JSON parse 性能优化 Graceful exit with cluster and pm Use Blanket.js instead of jscover 使用 connect-domain 捕获异步调用中出现的异常 Defense hash algorithm collision 防御hash算法冲突导致拒绝服务器 fibonacci(40) benchmark [nodejs]保证你的程序死了还能复活:forever and forever webui [nodejs]Buffer vs String Nodejs "Hello world" benchmark npm 资源库镜像 NodeBlog v0.2.0 更新说明 关于__proto__的链式记忆 NAE支持自定义域名了 Nodejs 离线文档下载 nodejs读写大文件 Nodejs HTTP请求的超时处理(Nodejs HTTP Client Request Timeout Handle) 在jQuery 1.5+ 的jqXHR上监听文件上传进度(xhr.upload) 关于Nodejs中Buffer释放的二三事 nodejs web开发入门: Simple-TODO Nodejs 实现版
基于 Postgres 实现一个 Job Queue
MK2 · 2025-06-20 · via 博客园 - MK2

今天看到一篇赞美 Postgres 的文章:Postgres is Too Good (And Why That's Actually a Problem) ,显然是非常吸引眼球的,作者用 PG 实现了需要用到的所有微服务。

做 AFFiNE 我们是用 Redis 的 pub/sub 实现的 Job Queue,所以想参考一下用 Postgres 实现对比看看。

直接问 ChatGPT 怎样实现

基于 Postgres 的 LISTEN/NOTIFY 实现任务队列服务

https://chatgpt.com/share/685527b8-724c-8010-9e5a-1aac521a7acc

表结构

init.sql

CREATE TABLE tasks (
  "id" SERIAL PRIMARY KEY,
  "type" TEXT NOT NULL,
  "payload" JSONB,
  "status" TEXT NOT NULL DEFAULT 'pending',
  "created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "updated_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "processed_at" TIMESTAMPTZ(3)
);

Job Queue 基本操作

添加任务并广播通知

INSERT INTO tasks (type, payload) VALUES ('send_email', '{"to": "test@example.com"}');

NOTIFY task_queue, 'new_task';

监听任务消息并拉取任务

监听任务消息

await jobListener.query('LISTEN task_queue');

jobListener.on('notification', async (msg) => {
  if (msg.channel === 'task_queue') {
    // 在这里拉取任务
  }
});

拉取任务 SQL

UPDATE tasks
SET status = 'processing', processed_at = NOW(), updated_at = NOW()
WHERE id = (
  SELECT id FROM tasks WHERE status = 'pending'
  ORDER BY created_at ASC LIMIT 1
  FOR UPDATE SKIP LOCKED
)
RETURNING *;

可运行的代码

先启动一个 Postgres 测试服务

docker run --name pg-container-job-queue-demo \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=test123123 \
  -e POSTGRES_DB=mydb \
  -v $(pwd)/init.sql:/docker-entrypoint-initdb.d/init.sql \
  -p 5432:5432 \
  -d postgres:16

启动 demo.ts 代码,每 5 秒触发一个任务,并打印结果

node demo.ts

完整代码

请移步 https://github.com/fengmk2/fengmk2.github.com/tree/master/blog/2025/job-queue-on-postgres

有爱

希望本文对你有用 _

原始文章地址:https://fengmk2.com/blog/2025/job-queue-on-postgres/README.html