2012-09-23 49 views
1

如果最好在此处或在Programmers.SE上询问此问题,那么如果我遇到此问题,请迁移。每个消息类型的单个消费者的分布式发布/订阅

首先,关于我想要实现的一点。我有一个node.js应用程序从一个来源(一个socket.io客户端)接收消息,然后对消息进行处理,这可能导致零或多个消息退出,或者发送给该发送者或该消息中的其他客户端组。

对于处理,我想本质上只是推送消息到一个队列中,然后它通过各种消息处理器,可能会启动自己的项目,最终,运行socket.io位通知“嘿,发回这条消息“

作为一个具体的例子,说一个用户登录到服务,然后登录消息被放置在队列中,授权处理器获取它,这是事情,然后放置一条消息回到队列中说客户端已被授权。这返回到连接到客户端的socket.io套接字以及其他可能感兴趣的客户端。它也可以转到其他可能希望对授权进行更多处理的子系统(查找用户信息,根据其数据发送更多信息给客户端等)。

如果我想要强耦合,这将很容易,但我之前尝试过,它只是去了一堆很脆弱的意大利面代码,我想避免这种情况。设置中的另一个问题是,这应该是集群能力,这是真正的问题出现的地方。可能有不止一个授权处理器正在运行。但授权信息只能处理一次。因此,简而言之,我正在寻找一种模式/技术,使我能够从根本上为消息拥有多个订阅者“群组”,并且每个群组只能处理一次该消息。

我想过可能让每个处理器的实例都会生成一个唯一的名字,这个名字将被用作Reids中的一个列表。然后该名称将被注册到某种调度处理程序中,并被放入该组用户的集合中。然后,当消息到达时,调度会从该集合中抽取一个随机成员,并将其放入该列表中。虽然看起来这样会起作用,但似乎有点过于复杂和脆弱。

核心问题是我从来没有设计过这样的系统,所以我甚至不确定使用或查找的恰当术语。如果任何人都可以为我指出正确的方向,我会非常感激。

回答

0

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

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

在接收端,订户所做的第一件事是尝试将它刚刚从发布商那里获得的消息ID添加到该组中接收到的消息集中,其中sadd。如果sadd返回0,则该消息已被另一个实例占用,并且它只是返回。如果返回1,则将完整消息从字符串键中拉出并发送给侦听器。

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

1

我觉得你的描述与https://www.getbridge.com/服务类似。我但它最终根据zeromq写我自己的,它允许你注册服务,请求 - > < - rec和渠道这是酒吧/小工。

至于设计,我使用的客户端 - >代理 - >服务&渠道这些都是插头,使用自动发现玩,你有服务注册他们与谁打开一个TCP连接的代理模式,使中间商的其他服务器可以与该代理组服务进行通信。然后内部服务和客户端通过unix套接字或ipc频道连接,这是首选。

相关问题