3

我不知道是在这里问这个更好,还是在 Programmers.SE 上问这个更好,所以如果我有这个错误,请迁移。

首先,关于我正在尝试实现的内容。我有一个 node.js 应用程序,它从一个源(socket.io 客户端)获取消息,然后对消息进行处理,这可能导致零个或多个消息返回到发送者或其中的其他客户端团体。

对于处理,我想基本上只是将消息推入队列,然后它通过可能启动自己的项目的各种消息处理器工作,最终,运行 socket.io 的位被通知“嘿,发送这个回消息”

作为一个具体的例子,假设用户登录服务,然后将该登录消息放入队列中,授权处理器在队列中获取它,执行此操作,然后将消息放回队列中,说明客户端已获得授权。这会返回到连接到客户端的 socket.io 套接字,以及可能感兴趣的其他客户端。它还可以转到可能想要对授权进行更多处理的其他子系统(查找用户信息,根据他们的数据向客户端发送更多信息等)。

如果我想要强耦合,这很容易,但我之前尝试过,它只会导致一团非常脆弱的意大利面条代码,我想避免这种情况。设置中的另一个关键是这应该是可集群的,这才是真正的问题所在。可能有多个授权处理器正在运行。但是授权消息应该只处理一次。

所以,简而言之,我正在寻找一种模式/技术,它允许我基本上拥有多个订阅者“组”来接收消息,并且每个组只处理一次消息。

我想也许让处理器的每个实例生成一个唯一的名称,该名称将用作 Reids 中的列表。然后,该名称将在某种调度处理程序中注册,并放入该组订阅者的集合中。然后,当消息到达时,调度从该集合中随机抽取一个成员,并将其放入该列表中。虽然这似乎可行,但它似乎有点过于复杂和脆弱。

核心问题是我从来没有设计过这样的系统,所以我什至不确定使用或查找合适的术语。如果有人能为我指出正确的方向,我将不胜感激。

4

3 回答 3

2

我认为您的描述类似于https://www.getbridge.com/服务。我这样做了,但最终基于 zeromq 编写了我自己的,它允许您注册服务,req -> <- rec 和作为 pub / sub 工作人员的频道。

至于设计,我使用了一个客户端 -> 代理 -> 服务和通道,它们都是使用自动发现即插即用的,您让服务向打开 tcp 连接的代理注册其模式,以便其他服务器上的代理可以通信与该经纪人集团服务。然后内部服务和客户端通过首选的 unix 套接字或 ipc 通道连接。

于 2012-09-24T00:24:04.360 回答
2

我最终围绕 redis 发布/订阅函数做了一些处理。每种类型的消息处理器都有一个“组名”,并且该组内可以有多个处理器实例(因此程序的多个实例可以运行以进行集群)。

发布消息时,我生成一个增量 ID,然后将消息存储在具有该 ID 的字符串键中,然后发布消息 ID。

在接收端,订阅者做的第一件事是尝试将它刚刚从发布者那里获得的消息 ID 添加到该组的一组接收到的消息中sadd。如果sadd返回0,则消息已经被另一个实例抓取,它只是返回。如果返回1,则从字符串键中提取完整消息并发送到侦听器。

当然,这依赖于 redis 是单线程的,我想这将继续如此。

于 2012-09-24T01:36:21.070 回答
1

您可能正在寻找的是 AMQP 协议实现,您可以在其中让队列获取自定义交换,并实现 pub-sub 模型。

RabbitMQ - 具有大量库的流行 amqp 协议实现

它也有 node.js 库

于 2012-11-05T14:47:00.930 回答