一个.db文件跨12种语言:honker多语言绑定互操作与跨语言消息传递实战
【免费下载链接】honkerSQLite extension + bindings for Postgres NOTIFY/LISTEN semantics with durable queues, streams, pub/sub, and scheduler项目地址: https://gitcode.com/gh_mirrors/ho/honker
🦛honker是一个 SQLite 扩展 + 多语言绑定项目,它把 Postgres 风格的 NOTIFY/LISTEN 语义带进 SQLite:一个普通的.db文件里就内置了持久化任务队列、事件流(Stream)、Pub/Sub 和定时调度,无需 Redis、无需消息代理、无需守护进程。它的核心卖点是多语言绑定互操作——Python、Node.js、Ruby、Go、Rust、.NET、Elixir、Bun、C++、JVM、Kotlin 共 12 种语言读写同一个.db文件,消息在语言之间自由流动。
本文面向新手,带你快速理解 honker 的跨语言消息传递为什么可行,以及如何落地。
为什么一个 .db 文件能打通 12 种语言?
传统做法是"业务表用 SQLite,队列用 Redis",于是出现双写一致性问题(业务写成功、队列写失败)和额外组件运维成本。honker 的思路很直接:
SQLite 是主存储,队列就应该住在同一个文件里。
在 honker 里,队列就是一张带部分索引的表,INSERT INTO orders和queue.enqueue(...)可以在同一个事务里提交——要么都成功,要么都回滚。这就是"事务性发件箱(Transactional Outbox)"模式,Simon Willison 也据此将 honker 视为该模式的 SQLite 实现。
多语言互操作的关键在于两点设计(源码见 honker-core/src):
- 统一的表结构:所有绑定共享同一套
_honker_*表,schema 由 Rust 定义、通过 SQLite 扩展安装。Python 写入的任务行,Go 或 Node 完全能认出来。 - 统一的唤醒机制:SQLite 没有服务端推送通道,honker 用共享 watcher 每 1ms 读一次
PRAGMA data_version计数器,事务一提交,其他语言的进程立刻被"叫醒",实现毫秒级的跨进程推送语义(源码:honker-core/src/honker_ops.rs、honker-core/src/kernel_watcher.rs)。
12 种语言绑定一览:支持矩阵
honker 的 BINDINGS.md 给出了权威的绑定支持矩阵,节选如下:
| 绑定 | 安装方式 | 队列 | 流 | 通知 | 调度器 | 唤醒路径 |
|---|---|---|---|---|---|---|
Pythonhonker | pip install honker | ✅ | ✅ | ✅ | ✅ | 共享 Rust watcher |
Nodehonker-node | npm install | ✅ | ✅ | ✅ | ✅ | 共享 Rust watcher |
Rubyhonker | gem install honker | ✅ | ✅ | 仅通知 | ✅ | 扩展 C ABI |
.NETHonker | dotnet add package Honker | ✅ | ✅ | ✅ | ✅ | 扩展 C ABI |
| Rust / Go / Bun | crate / 源码 / npm | ✅ | ✅ | ✅ | ✅ | Rust watcher / C ABI |
| Elixir / C++ / JVM / Kotlin | hex / 源码 / Maven | ✅ | ✅ | ✅ | ✅ | 各自封装 |
💡 值得注意:即便只用裸 SQL(SELECT load_extension('honker')),任何支持加载扩展的 SQLite 客户端(3.9+)也能调用honker_enqueue、honker_claim_batch、notify()等 SQL 函数,参与同一套消息系统——详见 README.md 的 SQL Extension 章节。
跨语言消息传递实战:三种典型链路
honker 仓库自带大量跨语言集成测试,可以直接当作"实战手册"阅读:
场景一:Python 入队,任意语言消费
最经典的链路。Python 侧在业务事务里原子地"写订单 + 入队",Node、Go、Ruby 等任何绑定都能认领任务:
import honker db = honker.open("app.db") emails = db.queue("emails") with db.transaction() as tx: tx.execute("INSERT INTO orders (user_id) VALUES (?)", [42]) emails.enqueue({"to": "alice@example.com"}, tx=tx) # 与订单同事务可运行的完整示例见 packages/honker/examples/atomic.py 和 packages/honker/examples/quickstart.py。
场景二:Node 发通知,Python 被唤醒
cross_lang_python_to_node.js 演示了双向 Pub/Sub:Python 进程内tx.notify("orders", {...}),Node 侧的监听器在事务提交后被 watcher 唤醒,用一条带索引的 SELECT 就读到了消息。反向的 cross_lang_node_to_python.js 覆盖了对称链路。
场景三:混合语言队列与死信
tests/test_ruby_python_interop.py 验证 Ruby 与 Python 共享队列、流、通知表:Ruby 入队 25 条任务,Python 侧按序认领并 ack,双方对"认领即删除、重试耗尽进_honker_dead死信表"的语义完全一致。tests/test_extension_interop.py 则证明了裸 SQL 扩展与 Python 绑定之间 schema、ack 语义的严格一致(包括重试、心跳、限流、调度、任务结果存储等全部语义)。
快速开始:跨语言协作三步走
- 装绑定:Python 用
pip install honker,Node 用 npm 包,.NET 用 NuGet 包,Go/Elixir/C++ 从 release 下载扩展库即可(路径解析规则见 BINDINGS.md 的 Extension Reach 表格,也支持HONKER_EXTENSION_PATH环境变量覆盖)。 - 打开同一个 .db 文件:任一语言
open("app.db")会自动引导 schema;已有 ORM 连接(SQLAlchemy、GORM、Drizzle、Hibernate 等)只需加载扩展并执行honker_bootstrap(),就能在 ORM 事务里发队列消息,保住原子性。 - 一个进程发、另一个进程收:发送方
enqueue/publish/notify,接收方claim循环或监听器,跨进程唤醒延迟默认约 1ms 量级,可用 bench/wake_latency_bench.py 在自己硬件上实测。
⚠️ 两个使用约束要记住:honker 面向单机 + 文件型SQLite(不要把两个服务器通过 NFS 写同一个.db);请使用文件数据库而非:memory:。
性能与进阶
- 现代笔记本上吞吐量可达每秒数千条消息,实测脚本见 bench/README.md 与 bench/real_bench.py
- 100 个订阅者仍共享 1 个 watcher,空闲监听零查询
- 除默认
data_version轮询外,还有实验性的内核事件(kernel)与 WAL 共享内存(shm)两种 watcher 后端,各绑定的暴露方式见 BINDINGS.md 的 Watcher Backends 章节 - 各语言绑定源码位于 packages/,核心引擎位于 honker-core/,SQLite 可加载扩展位于 honker-extension/
小结
honker 用"一行 SQL 函数 + 一张表 + 一个 watcher"的组合,让 12 种语言在同一个.db文件上实现了队列、流、Pub/Sub 与调度器的完整互操作。如果你的项目已经以 SQLite 为主存储,又想要跨语言的可靠消息传递,它是一个值得一试的方案。
📌 延伸阅读:
- 绑定支持矩阵:BINDINGS.md
- Python 示例合集:packages/honker/examples/README.md
- 路线图:ROADMAP.md
- 变更日志:CHANGELOG.md
【免费下载链接】honkerSQLite extension + bindings for Postgres NOTIFY/LISTEN semantics with durable queues, streams, pub/sub, and scheduler项目地址: https://gitcode.com/gh_mirrors/ho/honker
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考