PgQue 重试与死信队列(DLQ)完整指南:构建可靠 Postgres 消息投递的黄金模式
【免费下载链接】PgQuePgQue – Zero-bloat Postgres queue built on top of on battle-proven Skypes PgQ. One SQL file to install, pg_cron to tick https://pgque.dev项目地址https://gitcode.com/gh_mirrors/pg/PgQue点击查看免费下载PgQue 是一款零膨胀Zero-bloat的 Postgres 消息队列基于 Skype 久经考验的 PgQ 架构重构用纯 SQL 实现一个 SQL 文件即可安装。本指南带你完整掌握 PgQue 的重试机制与死信队列DLQ通过nack延迟重投、max_retries控制重试上限以及dlq_inspect/dlq_replay/dlq_purge检查、回放与清理死信构建不丢消息、不重复投递的可靠投递模式。为什么 Postgres 队列需要重试和 DLQ任何消息系统都会遇到两类失败瞬时故障下游服务暂时不可用、网络抖动、数据库短暂锁冲突——这类失败等几十秒后重试往往就能成功永久性故障数据校验失败、代码 bug、下游契约变更——无限重试只会造成重试风暴拖垮整个队列。SKIP LOCKED风格的队列PGMQ、River、pg-boss 等在重试时依赖UPDATEDELETE反复失败的消息会产生大量死元组最终撞上 VACUUM 瓶颈。而 PgQue 的热路径从不删除行重试和死信都走独立的retry_queue与dead_letter表主事件流保持零膨胀——这正是零膨胀重试模式的价值所在。PgQue 的投递模型是快照批量生产者send事件ticker 每 100ms 打一个 tick消费端的receive按 tick 之间的批次读取。重试消息到期后重新插回事件流下一次 tick 就会再次可见。下图是 PgQue 官方 tick 速率基准测试测得的端到端投递延迟分布可以直观理解重试间隔 tick 周期如何构成重投延迟PgQue 重试机制如何工作nack 与 retry_after 详解重试的入口是nack负确认。消费循环的标准形态是-- 处理成功整批确认游标前进 select pgque.ack(batch_id); -- 处理失败单条 nack延迟 60 秒后重投并记录原因 perform pgque.nack(batch_id, msg, interval 60 seconds, validation failed);pgque.nack(batch_id, msg, retry_after, reason)的行为源码见 receive.sql若该事件的ev_retry小于队列的max_retries有效默认值 5把事件放进pgque.retry_queue并设置重投时间 当前时间 retry_after若ev_retry max_retries则路由进死信表pgque.dead_letter到期后由维护函数pgque.maint_retry_events()把到期事件搬回事件表生产环境由pgque.start()每 30 秒自动调度无需手动调用。两个容易踩坑的点nack与ack是配合关系不是二选一。nack逐条安排重试或死信ack逐批确认并推进消费位点不做ack消费者就永远卡在这一个 batch 上retry_after默认 60 秒。实现指数退避时可以依据返回消息中的retry_count字段动态计算如60 * 2^retry_count秒。receive返回的每行都带retry_count首次投递为 NULL天然支持逐级退避。完整的逐步演练发送坏消息 → nack → 观察retry_count递增 → 进入 DLQ → 回放请阅读官方教程 docs/tutorial.md 的 Step 7 与 Step 8。max_retries 配置与死信路由规则每个队列可独立设置重试上限select pgque.set_queue_config(orders, max_retries, 10);queue_max_retries列的默认值是 SQLNULLnack内部按coalesce(queue_max_retries, 5)计算所以有效默认值是 5 次重试详见 docs/reference.md 的 Queue config 一节参数校验逻辑在 queue_max_retries.sql。死信路由的判定条件是coalesce(ev_retry, 0) max_retries。以max_retries 2为例推演第几次 nack存储的 retry_count判定结果100 2 不成立重试计数变为 1211 2 不成立重试计数变为 2322 2 成立进入pgque.dead_letter也就是说最多重试 2 次意味着总共投递 3 次。整个死信表的建表与event_dead的幂等插入逻辑重复 nack 同一条终态消息只产生一行 DLQ见 dlq.sql。死信队列DLQ检查、回放与清理SQL 操作速查PgQ 原始版本只有重试队列死信队列是 PgQue 新增的能力。所有 DLQ 函数汇总如下签名与权限见 docs/reference.md函数作用所需角色dlq_inspect(queue, limit100)按时间倒序列出该队列的死信含dl_reason、原始 payloadpgque_readerdlq_replay(dl_id)回放单条重新入队并删除 DLQ 行返回新事件 idpgque_writerdlq_replay_all(queue)回放整个队列的死信逐条隔离失败返回(replayed, failed, first_error)pgque_writerdlq_purge(queue, older_than30 days)删除超过时限的死信返回删除条数pgque_admin日常运维四件套-- 1. 检查最近 20 条死信及失败原因 select dl_id, dl_reason, ev_type, ev_data from pgque.dlq_inspect(orders, 20); -- 2. 修复上游 bug 后单条回放带新 ev_id 重新入队 select pgque.dlq_replay(42); -- 3. 一键回放整队failed 0 时查看 first_error select replayed, failed, first_error from pgque.dlq_replay_all(orders); -- 4. 清理 7 天前的死信默认 30 天 select pgque.dlq_purge(orders, interval 7 days);注意dlq_replay_all返回的是 record 而非整数——读取时务必按列名取replayed / failed / first_error。回放属于生产动作所以授予pgque_writer纯消费角色只能inspect。客户端重试黄金模式Python / Go / TypeScript 官方库实战PgQue 提供 Python、Go、TypeScript 三个官方客户端clients/python、clients/go、clients/typescript都封装了同一个send / receive / ack / nack面。以 Python 客户端为例consumer.py 的常驻消费者默认行为就是重试黄金模式处理器抛出异常 → 自动nack默认retry_after60秒事件类型没有注册处理器 → 同样nack可用unknown_handler_policy改为ack丢弃重试耗尽后消息自动进入dead_letter客户端不感知、不会阻塞。import pgque with pgque.connect(postgresql://localhost/mydb) as client: client.handler(order.created) def handle(msg): call_downstream(msg.payload) # 抛异常 自动 nack 重试 client.listen(orders, processor) # 异常自动 nack(60s) → 5 次后进 DLQ三条落地建议用retry_count做指数退避——SQL 侧可写perform pgque.nack(bid, msg, (60 * power(2, coalesce(msg.retry_count,0)))::int * interval 1 second, reason)业务写库要与ack同一事务才能获得 exactly-once 效果模式见 docs/examples.md 的 Exactly-once processing 一节消费端幂等PgQue 默认 at-least-once重试必然带来重复投递的可能处理器应按msg_id去重。监控重试风暴与 DLQ 深度告警信号速查表重试与死信是最值得告警的信号。docs/monitoring.md 给出的阈值表中与本章直接相关的有两条信号来源告警条件含义DLQ 深度pgque.dead_letter计数 /dlq_inspect死信积压持续增长或预期为零却非零有下游在反复失败重试已耗尽重试速率pgque.error_rate(queue, period, bucket)重试分桶值异常抬升瞬时故障正在放大为重试风暴两条最常用的只读查询pgque_reader即可执行-- 各队列死信深度 select dl_queue_id, count(*) as dlq_depth, max(dl_time) as latest from pgque.dead_letter group by dl_queue_id order by dlq_depth desc; -- 按时间桶看重试与死信速率 select * from pgque.error_rate(orders, interval 1 hour, interval 5 minutes);经验法则DLQ 非空本身就是事件——它说明有消息连续失败超过max_retries次此时应先看dl_reason与ev_data定位下游故障修复后再回放而不是扩大重试上限。常见坑点与最佳实践清单nack后忘了ack消费者永远停在该 batch推荐用单个DO块receive → 逐条处理/nack → 批量 ack教程 Step 7 的原样模式⏱️send、ticker、receive必须各自独立事务ticker 的快照必须晚于send提交重试事件搬回后亦然snapshot rule见 docs/concepts.mddlq_replay返回的是新ev_id原事件 id 不复用依赖ev_id做幂等的系统要留意队列删除会级联清空死信dead_letter的外键是on delete cascade需要留档的审计数据请先dlq_purge前导出或复制⚙️调max_retries前先调retry_after上限是熔断间隔才是节流两者配合才能吸收长尾故障告警看趋势不看单点DLQ 深度与lag连续多个采样点增长再告警避免 tick 抖动误报。总结PgQue 把重试 死信做成了队列的内建能力nack一个函数同时承担退避重投与死信路由retry_queue/dead_letter两张表让失败流量与主事件流彻底隔离配合零膨胀的快照批量架构重试风暴也不会污染热路径。配合三个官方客户端的自动 nack 语义和error_rate监控你就获得了一套完整的可靠投递体系——不丢消息、不重试风暴、失败可审计、可回放、可清理。下一步建议阅读 docs/tutorial.md 亲手跑一遍 Step 7/8并在 tests/acceptance/us3_retry_dlq.sql 中查看该流程的完整集成测试实现。赞分享【免费下载链接】PgQuePgQue – Zero-bloat Postgres queue built on top of on battle-proven Skypes PgQ. One SQL file to install, pg_cron to tick https://pgque.dev项目地址https://gitcode.com/gh_mirrors/pg/PgQue点击查看免费下载相关推荐JEECG-Boot消息队列实战RabbitMQ可靠消息投递与死信队列处理完整指南JEECG Boot消息队列实战RabbitMQ可靠消息投递与死信队列处理完整指南 JEECG Boot作为一款优秀的企业级快速开发框架集成了强大的 Rab低代码后端前端AI 应用大模型RAG工作流自动化Orleans与消息队列可靠性消息重试与死信队列Orleans与消息队列可靠性消息重试与死信队列 在分布式系统中消息传递的可靠性直接影响系统稳定性。Orleans作为微软开发的分布式计算框架提供了完善的后端微服务node-interview消息可靠性消息重试与死信队列node interview消息可靠性消息重试与死信队列 你是否曾遇到过消息发送失败导致订单状态异常或者因网络波动造成关键通知丢失在分布式系统中消息传递文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Vue3+Cesium集成实战:天地图、高德地图图层切换与坐标系纠偏

Vue3+Cesium集成实战:天地图、高德地图图层切换与坐标系纠偏

1. 先别急着写代码:Vue 3 与 Cesium 集成前的心态与设计Cesium 不是一套“能在 Vue 里面跑的库”那么简单。它是一个典型的重型三维地球引擎,拥有自己独立的事件循环、渲染状态机和资源管理系统。当你试图把它塞进 Vue 3 的响应式体系里,最容…

2026/10/10 20:01:27 阅读更多 →
为什么你降完AI导师一眼看穿2026去AI味实测排名第一教你改出真人学术语感

为什么你降完AI导师一眼看穿2026去AI味实测排名第一教你改出真人学术语感

为什么你降完AI导师一眼看穿?2026去AI味实测排名第一:教你改出真人学术语感【实测测评结论速览】 经过盲审评委与资深导师真实审读盲测,2026 年论文去 AI 味与真人语感精修实测第一名为助研君(gradu.cn)。针对“导师一…

2026/10/10 20:01:27 阅读更多 →
AnyPS5:PS5游戏库管理与跨区存档备份的命令行助手

AnyPS5:PS5游戏库管理与跨区存档备份的命令行助手

相信每一位长期玩PS5的玩家都会遇到同一个尴尬时刻:游戏库里数字版、试玩版、会免版混成一堆,想找某个游戏得翻半天;想查某个跨区版本有没有中文,得开好几个网页;更别提备份存档、清理截图、整理DLC这些琐碎事&#xf…

2026/10/10 20:01:27 阅读更多 →

最新新闻

别再把 Anki 吹成「认知操作系统」了:工具崇拜正在毁掉你的学习

别再把 Anki 吹成「认知操作系统」了:工具崇拜正在毁掉你的学习

别再把 Anki 吹成「认知操作系统」了:工具崇拜正在毁掉你的学习 【免费下载链接】anki Anki is a smart spaced repetition flashcard program 项目地址: https://gitcode.com/GitHub_Trending/an/anki 从「背单词神器」到「认知操作系统」:一种叙…

2026/10/10 20:51:34 阅读更多 →
文献检索式进阶:从关键词到高级检索的完整指南

文献检索式进阶:从关键词到高级检索的完整指南

昨晚有人把一份文献检索式发给我,说是从某篇论文里扒来的“高阶模板”,在知网里执行了半天,结果页从头到尾只有16条记录。我扫了一眼就发现问题:同义词之间全用的AND,字段代码写错,还在不该加引号的地方加了…

2026/10/10 20:51:34 阅读更多 →
Django建材销售平台实战:三端角色权限与SKU订单设计全解析

Django建材销售平台实战:三端角色权限与SKU订单设计全解析

做建材类电商项目的时候,很多人第一反应是“这不就是个多用户商城吗”。但真上手之后你会发现,建材这个行业和卖衣服卖数码完全不一样,SKU维度极其复杂,角色之间又有很强的数据隔离需求。我最近刚好完整做了一个基于Django的建材销…

2026/10/10 20:51:34 阅读更多 →
SpringBoot+Vue前后端分离旅游平台实战:从开发到部署上线

SpringBoot+Vue前后端分离旅游平台实战:从开发到部署上线

花两周时间把一个前后端分离的旅游平台从零跑到部署上线,是什么体验?说实话,这和网上那些只教你某个局部功能的教程完全不同——你面对的是数据库建模、接口设计、Vue页面开发、前后端联调、服务器部署一整条链路,任何一个环节出问…

2026/10/10 20:51:34 阅读更多 →
JavaScript核心知识拆解:从类型判断到跨环境调试的实践指南

JavaScript核心知识拆解:从类型判断到跨环境调试的实践指南

我很少公开说这种话,但学 JavaScript 这件事,值得每个写代码的人认真对待。倒不是因为它是哪种“最好的语言”,而是它的应用范围实在太广:浏览器里的页面交互、服务端的 Node.js 中间层、小程序、桌面端工具、甚至数据库的存储函数…

2026/10/10 20:51:34 阅读更多 →
人工合规审查有盲区,智能合规如何补足文件风险识别短板

人工合规审查有盲区,智能合规如何补足文件风险识别短板

合同、规章制度、对外函件、合作协议企业日常经营中,海量文本文件里潜藏着大量合规风险。传统人工文件合规审查存在天然短板:依赖个人经验、受精力限制、批量文件极易漏审。许多隐性合规漏洞藏在细碎条款之中,人工难以全覆盖排查。一旦文件落…

2026/10/10 20:50:33 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →