Golang高性能消息服务实现方案

Golang高性能消息服务实现方案 我正在寻找一个分布式系统消息传递包(类似于spread这样能提供可靠有序消息传递的工具)。有谁知道我应该关注哪些方案吗?

分布式系统概念对我来说还比较陌生,可能我理解有误,但像RabbitMQ这样的消息代理并不完全符合需求,对吗?据我了解,它处理的是底层的消息分发,但无法保证可靠性或消息顺序。如果我说错了请指正 🙂

6 回复

该主题在上次回复后已自动关闭90天。不再允许新的回复。

更多关于Golang高性能消息服务实现方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你是指用Go语言编写的NSQ吗? GitHub上有11.5K星标:https://github.com/nsqio/nsq 功能特性:http://nsq.io/overview/features_and_guarantees.html 这里有一篇关于Segment如何将NSQ扩展到7500亿条消息的博客文章:https://segment.com/blog/scaling-nsq/

我确实研究过NSQ,它似乎是我最好的选择,但从文档来看:

stangeorge:

功能:NSQ文档1.2.1 - 功能与保证

您不能依赖消息传递给消费者的顺序。

与消息传递语义类似,这是重新排队、内存和磁盘存储组合以及每个nsqd节点不共享任何内容的结果。

使用Spread可以保证所有节点上消息的完全顺序。遗憾的是,我尚未在Go中找到能够提供这种级别顺序保证的方案。

你真的需要保证消息的顺序吗?在不可信的环境中又如何实现呢?

保证顺序本质上意味着无论有多少工作进程,每次只能顺序传递一条消息。

假设工作进程A正在处理消息1,工作进程B正在处理消息2。如果A在处理过程中崩溃而无法确认,消息分发器需要重新发送消息1,但此时消息2已经传递并可能已被确认——当你想要保证顺序时,这就形成了一个两难局面。

这就是为什么我认为在分布式系统中保证顺序是个糟糕的主意。

不过有时候我确实理解局部顺序的需求(比如用户在被创建之前不能被删除),在我维护的遗留系统中,这个问题是通过重新排队那些暂时无意义的消息来解决的,直到它们变得有意义或者超过有效期。

在某些情况下,消息的顺序至关重要。例如,PAXOS算法就依赖于完全有序性。至少,消息之间可能存在因果依赖关系,这就要求对消息的传递进行排序。

这或许是个简单的例子,但假设有两个发送消息的进程(P1和P2)和一个观察者进程(P3)。P1广播消息m1:“P2,你家房子烧毁了”,然后是m2:“愚人节玩笑!”。P2接收到m1和m2后,回复m3:“哈哈哈,真好笑!”。如果违反因果依赖关系,P3可能先看到m1、m3,然后才看到m2(这会让P3非常困惑)。P3也可能根据这种顺序做出决策,但m3是基于看到m1和m2后才广播的。

若不对消息进行排序,就无法满足因果依赖关系。

对于Golang实现高性能消息服务,推荐以下方案:

1. NATS Streaming (现为NATS JetStream)

  • 提供持久化、可靠有序的消息传递
  • 支持At-Least-Once和Exactly-Once语义
  • 与Go集成良好,性能出色
  • 支持消息重放和消费者组

2. Apache Pulsar

  • 云原生消息系统,支持多租户
  • 保证消息顺序和持久化
  • 提供分层存储,扩展性强
  • 官方提供Go客户端

3. Redis Streams

  • 基于Redis的轻量级方案
  • 支持消息持久化和消费者组
  • 提供基本的有序保证
  • 部署简单,适合中小规模场景

关于RabbitMQ的补充说明: RabbitMQ通过以下机制保证可靠性和顺序:

  • 持久化队列和消息
  • 生产者确认机制
  • 消费者确认机制
  • 单队列内保证FIFO顺序

但确实在分布式场景下,严格的全序保证需要额外设计。上述方案在分布式环境中提供了更好的有序性和可靠性保证。

建议根据具体场景选择:NATS适合云原生环境,Pulsar适合大规模企业级应用,Redis Streams适合轻量级需求。

回到顶部