Siberite Fanout队列完整教程:1条set命令写入多个队列,快速实现消息广播

发布时间:2026/8/22 13:36:45
Siberite Fanout队列完整教程:1条set命令写入多个队列,快速实现消息广播 Siberite Fanout队列完整教程1条set命令写入多个队列快速实现消息广播【免费下载链接】siberiteSiberite is a simple, lightweight, leveldb backed message queue written in Go.项目地址: https://gitcode.com/gh_mirrors/si/siberiteSiberite 是一款基于 LevelDB 的轻量级消息队列服务器用 Go 编写。它的Fanout 队列功能允许你用一条set命令把同一条消息同时写入多个队列轻松实现消息广播。本教程面向新手带你从零跑起 Siberite理解 Fanout 语法并看懂广播在源码中的实现原理。上图Siberite 在 10 个队列上的洪水式写入flood基准测试展示了其多队列高吞吐写入能力什么是 Fanout 队列为什么需要消息广播先理解一个常见场景你的系统里有订单服务、日志服务、邮件服务它们都需要收到同一条用户下单消息。传统做法是业务代码逐条往 3 个队列里发 3 次set——代码冗余而且多次写入之间没有天然的一致性。Siberite 的 Fanout 队列也称扇出队列就是为解决这个问题而设计的一条命令多处投递set queueAqueueBqueueC ...一次网络往返同一条消息进入 3 个队列每个队列独立消费各队列仍然是严格的 FIFO不同下游服务各自消费自己的队列互不影响持久化存储底层由 LevelDB 落盘消息不因重启丢失且常驻内存极低。快速安装3步启动Siberite消息队列服务器第 1 步获取代码并编译git clone https://gitcode.com/gh_mirrors/si/siberite cd siberite go build siberite.go第 2 步准备数据目录mkdir ./data第 3 步启动服务器./siberite -listen localhost:22133 -data ./data看到listening on 127.0.0.1:22133即启动成功。启动参数定义在 siberite.go 中-listen指定监听地址默认0.0.0.0:22133-data指定数据目录默认./data。Fanout队列用法一条set命令同时写入多个队列Siberite 沿用 memcache 的 TCP 文本协议可以直接用 telnet 体验零门槛telnet localhost 22133普通写入单队列 setset work 0 0 10 1234567890 STORED格式是set 队列名 flags exptime 字节数下一行是消息体结尾\r\n返回STORED表示成功。广播写入多队列 setFanout把多个队列名用号连接即可set worklogmail 0 0 10 1234567890 STORED这一条命令消息1234567890就同时进入了work、log、mail三个队列。随后各队列可以独立取出且互不干扰get work VALUE work 0 10 1234567890 END get log VALUE log 0 10 1234567890 END get mail VALUE mail 0 10 1234567890 END注意普通的get 队列是消费型读取取出即删除所以三个队列必须各读一次消息才不会丢。结合持久游标一条消息被反复读取除了一次消费Siberite 还支持get 队列.游标名的持久游标语法——游标会记录读取位置但不删除源消息。配合 Fanout可以实现广播一次、多路重放set eventsarchive 0 0 5 hello STORED get events.cursor1 get events.cursor1 # 继续从上次位置读取游标数量不限非常适合新消费者追赶历史消息的场景。源码解析 号如何触发扇出广播Fanout 的实现非常精巧核心就在 controller/set.go 中。1️⃣ 解析阶段parseSetCommand检查队列名中是否含有有则按切分成队列名列表if strings.Contains(cmd.QueueName, ) { cmd.FanoutQueues strings.Split(cmd.QueueName, ) cmd.QueueName cmd.FanoutQueues[0] }这里有个巧妙的设计queue/queue.go 中队列名的合法字符正则[^a-zA-Z0-9_\-:\#\$%\,\\~*!]并不包含所以在协议里永远是分隔符不会与队列名冲突。2️⃣ 写入阶段Set方法遍历FanoutQueues把同一份数据块依次Enqueue到每个队列的 LevelDB 存储中任何一个队列写入失败命令立即返回错误注意先写入的队列不会回滚属于部分成功的语义生产环境建议客户端做幂等处理。3️⃣ 测试验证controller/set_test.go 中的Test_Controller_SetFanout用testfanout_test12四个队列做广播并断言每个队列长度均为 1、取值内容一致——这正是官方对 Fanout 正确性的保证。性能参考低内存与高吞吐的 LevelDB 消息队列Siberite 把消息全部存储在进程外LevelDB因此无论队列多大常驻内存都保持很低。官方基准测试见 docs/benchmarks.md上图常驻内存对比。队列规模增长到 52 万条时Siberite 仅约 94 MB而内存型方案 Kestrel 已达 800 MB在多队列洪水写入场景上节首图中Siberite 在 100 连接下达到约 74000 requests/s是三者中最高的。这意味着Fanout 广播并不会成为性能瓶颈——即使一条消息要扇出到多个队列吞吐依然可观。常见疑问 FAQQ1Fanout 最多可以写多少个队列协议层面没有硬限制分隔的队列数越多单次set的写入开销越大。实践中广播到 3~5 个队列最为常见。Q2广播是原子操作吗不是。各队列依次写入中途失败会返回错误但已写入的队列不回滚。需要强一致的下游请结合消费端幂等设计。Q3可以用现有的 memcached 客户端吗可以。Siberite 兼容 memcache TCP 文本协议Ruby、Go 等语言都有兼容客户端清单见 docs/clients.md。可靠读取two-phase fetch需要客户端保持长连接。Q4队列名里能用吗不能。被保留为扇出分隔符包含的队列名会触发多队列广播语义而非创建单个名为ab的队列。总结能力语法效果单队列写入set work 0 0 n消息进入 1 个队列Fanout 广播set worklogmail 0 0 n同一条消息进入 N 个队列消费型读取get work取出并删除消息游标读取get work.cursor1不删消息可重放Siberite 的 Fanout 队列用最小的语法成本一个号解决了消息广播问题再加上 LevelDB 带来的低内存与持久化非常适合轻量级微服务解耦、日志分发、多消费者订阅等场景。下一步建议动手用 telnet 完成上面的完整流程体验一次真实的消息广播。【免费下载链接】siberiteSiberite is a simple, lightweight, leveldb backed message queue written in Go.项目地址: https://gitcode.com/gh_mirrors/si/siberite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻