使用Redis存储扩展Engine.IO(与Socket.IO相比)

13

这个主题有几个问题,但并没有一个完全解决这个问题。

我正在使用Socket.IO与redis存储,并为访问量的增加做好准备。我的托管公司说:“你需要使用Engine.IO代替Socket.IO,因为它更有效率”,所以我正在努力弄清楚这意味着什么。

这样的问题似乎有矛盾的答案:

所以,在我看来:

  • Socket.IO 0.9降级
  • Engine.IO增强
  • Socket.IO 1.0将使用Engine.IO
  • 如果要在多个实例上运行Engine.IO,则必须自己编写redis存储器

然而Engine.IO称其为“负载均衡器友好型”,但没有提到redis。它肯定有某种外部存储,对吗?但是,如果它具有多个传输和存储器,则Socket.IO的意义何在?

然后我发现Socket.IO 可能已被放弃,知名公司正在转向使用Primus

如何扩展Engine.IO?我必须自己写存储器吗?


如果你选择使用Engine.IO,是需要自己编写存储器的。我知道抱怨开源项目缺乏更新并不酷,但我感觉Socket.IO在这方面做得不够好。有很多类似这样的问题,而1.0版本已经拖延了半年多的时间。Socket.io上有数百个未解决的问题,其中许多已经存在数月之久,因此看起来它已经无人维护了。 - Timothy Strimple
如果你想使用engine.io,那么是的,你需要编写额外的内容。我想socket.io正在面临一些适应新核心的障碍。Socket.io就像Express对于Connect一样,它隐藏了engine.io的低级细节,并且灵活且用户友好。但是我建议你不要在其上构建存储,因为同样的原因。socket.io 1.0是基于engine.io承诺构建的。鉴于socket.io 1.0的状态,有人能保证engine.io会成功吗?如果1.0正在进行中,请等待它,因为如果它出现,它将比您所做的更好。 - user568109
3个回答

10

我希望分享一下我这个星期学到的东西,但希望有人能来回答这个问题,从而让我可以确认答案。

1)永远不要使用Socket.IO(截至版本0.9.16)

我的主机建议我使用Engine.IO(或其他任何东西),他们是对的。Socket.IO有很多重大问题,其中最糟糕的是它会意外地攻击你的服务器。我亲身经历了这种情况,即使只有很少的客户端,也完全使我的服务器瘫痪,直到我放弃Socket.IO。我扩展到25个以上的无人机来吸收打击,但这没有用。单个客户端可以每秒发送1000多个请求。

2)其他引擎没有Redis存储

Socket.IO允许您通过其Redis存储在节点之间广播。就我所知,Engine.IO、Primus和SockJS都没有提供此功能。因此,当这些引擎声称“负载均衡器”友好时,这并不意味着您可以在节点之间广播消息。我开始认为这实际上是件好事。使用redis编写发布/订阅相对容易,并且将其分开很好。

我最终使用PrimusEngine.IO,然后使用redis发布/订阅在节点之间共享事件。花了我大约5个小时的时间移除Socket.IO、将Primus与其他工具连接起来、编写发布/订阅代码并上线。到目前为止,这种体验要好得多。

更新:

最终我使用SockJS,因为Engine.IO也会陷入重新连接的循环(每秒几次)。它给我提供了最佳的连通性和稳定性,并且Primus现在处理重新连接问题(SockJS不这样做)。


嘿,现在你已经从引擎切换到SockJS了,Redis的发布/订阅机制还能正常工作吗?你还能够通过Redis进行扩展吗? - Harry
1
需要明确的是,Redis pub/sub并没有内置在engineio或sockjs中。我完全独立地连接了Redis。由于我使用的是Primus,因此切换并没有改变Redis部分。 - bendytree
为什么不使用Primus + Redis pub/sub并添加SockJs层? - hfcorriez
一个单独的Socket IO客户端可以每秒发送数千个请求,为什么不简单地创建一个时间变量来存储此套接字上次发送请求的时间,如果例如小于一毫秒,则此套接字正在垃圾邮件并断开它。或者您可以使用任何其他自定义检查来执行类似的操作,以阻止垃圾邮件套接字和滥用用户。除非我误解了您在Socket IO方面的问题... - Joe Yahchouchi

1
我认为在Socket.IO发布v1.0版本之前应该避免使用它,因为它存在缺陷,在我的测试中Engine.IO表现更好(https://medium.com/node-js-javascript/b63bfca0539)。Primus也是一个不错的选择:也许你现在会使用Engine.IO,但当Socket.IO 1.0发布后,你可能会想切换到它。
我用Engine.IO、Redis和Pub/Sub结构实现了一个类似的程序,看起来非常优雅。下面的代码将连接的客户端订阅到一个房间/频道中。
io.on('connection', function (socket) {
  var observerRedisClient = redis.createClient();
  observerRedisClient.subscribe(resourceId, redis.print);

  observerRedisClient.on('message', function(channel, message) {
      socket.send(message);
  });
});

如果您更新该频道,即保存某些数据并发布,则所有订阅的客户端都将收到此数据。
redisClient.set(key, value, redis.print);
redisClient.publish(key, value);

如果您感兴趣,该代码是开源的:https://github.com/denizozger/node-engine.io-server

-1

嗯,正如你所提到的,我应该看一下Primus。使用HAProxy可以实现扩展。 作为底层通信,您仍然可以使用Socket.io,但也可以使用engine.io。通过使用Primus,您可以尝试不同的库。 关于在http://pusher.com/docs/server_libraries扩展Redis方面有一篇有趣的文章。


请记住,它推荐使用HAProxy进行粘性会话,这意味着它应该始终将具有相同会话的人重定向到同一台机器。 它这样做是为了代替连接信息的公共存储。每种方法都有一些优缺点,因此在决定之前,请确保您了解这些内容。https://dev59.com/FnI_5IYBdhLWcg3wDOdC - Timothy Strimple
我并没有做出决定。我只是想帮忙并指向其他人写的一些文章。感谢你的降级。 - Kurt Pattyn
我知道。那是针对楼主的。 - Timothy Strimple

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接