负载均衡多实例集群背后的事件源

Eventsource behind a load balanced multi instance cluster

我编写了一个简单的 Web 应用程序来打印 http request via Eventsource。然而我意识到当部署在一个典型的 ECS 集群中时,即在负载均衡器后面的 至少两个 实例上,如果用户连接到一个实例并且挂钩被另一个实例接收(假设负载均衡器分派两个不同的实例),请求将不会显示。

在将其他(有状态的?)应用程序安装到这种在负载均衡器后面旋转新实例的 AWS 扩展部署风格之前,我已经看到过此类问题。它有名字吗?有关如何修复我的程序以使其适合 AWS 模型的任何建议吗?我想钩子需要写入某个数据存储区,并且事件源发布者需要轮询或者更确切地说是来自它的事件?

我个人的意见是,你应该找到一项关键技术(推送通知、PubNub、Aws IOT,Firebase)来帮助你解决这个问题,而不是自己构建。

这些 HTTP 实例是有状态的,因此您需要能够在它们之间共享状态。 扩展持久连接很困难,在它前面使用循环负载平衡器会变得更加困难。 我建议您寻找可以为您完成所有这些工作的服务。

如果你想自己动手,我建议你看看:

  • Redis。每个用户使用一个队列。
  • Rabbit MQ - 为每个用户创建一个队列。我认为这不会扩展,但也许它适用于您的情况。
  • 使用某种类型的聚类框架。我不知道去。 Erlang/Elixir 或 Akka 等平台支持集群。通常,您可以连接到集群的任何节点,消息将传送给您。

这些实时系统不能很好地使用 request/response/polling 模型进行扩展。如果您不需要它来扩展,只需将您的数据存储在 mysql 或 REDIS 中并对其进行轮询。

负载均衡多实例集群背后的 EventSource SSE

Pull request: https://github.com/unee-t/showhook/pull/1

负载均衡器后面的服务器需要随时了解 /events。当相邻服务器接收到事件时,该服务器必须将接收到的事件通知群组。

用法示例

获取存储库。

git clone git@github.com:stephenlb/showhook.git
cd showhook

您必须使用 make 设置项目。

make build
make network

现在您可以 运行 您的容器了。请注意,我们有一个包含您的二进制文件的 12MB 容器。我们通过在 Dockerfile 中创建一个构建容器和一个 运行time-container 使容器变小。这使容器从 400MB 减少到 12MB。

PORT=9000 NEIGHBORS=192.168.0.1:9001 make start
PORT=9001 NEIGHBORS=192.168.0.1:9000 make start

现在打开浏览器加载 html 文件。

  1. http://0.0.0.0:9000
  2. http://0.0.0.0:9001

在第三个选项卡中单击页面上的 /hook link。请注意,您的前两个选项卡将收到 EventSource 通知。

已更新 main.go 应用程序服务器

/hook-neighbor 事件处理程序上向您的邻居添加 HTTP 调用。您可以将代码添加到现有的 Go 代码中,以通知相邻服务器了解该事件。这将允许任何客户端接收事件,而不管在 EventSource('/events').

上订阅的服务器是什么

动态添加新的事件服务器

当您需要向上和向下扩展时,您需要 add/remove 服务器。让您的服务器了解新邻居的一种简单方法是使用服务发现。您可以考虑添加 Service Discovery 例如 etcd and consul.

你有一个很好的开始!我用类似的方法构建了 PubNub Network

SNS + SQS 扇出

在我看来,这个问题可以使用 SNS + SQS 巧妙地解决扇出 模式。您可以通过 SNS 主题 来构建它,其中一项服务将发布特定消息(根本不关心消费者 - 这有助于解耦)并且您可以让队列订阅该主题,而其他服务服务将能够按照自己的节奏使用相同的消息。所以,是的,这将解决许多接收者(或订阅者)的问题。

会是这样的:

You have a topic (TopicX) on SNS

Service B has its own queue (QueueB); QueueB is subscribed to TopicX

Service C has its own queue (QueueC); QueueC is subscribed to TopicX

Service A performs an operation that needs to be shared across your network

Service A publishes Message1 to TopicX

QueueB receives Message1

QueueC receives Message1

ServiceB consumes Message1

ServiceB deletes Message1 from QueueB

ServiceC consumes Message1

ServiceC deletes Message1 from QueueC

查看 https://docs.aws.amazon.com/sns/latest/dg/SNS_Scenarios.html 了解有关此模式的更多详细信息。