如何让一个Redis客户端等待所有其他Redis客户端响应?

时间:2018-04-24 11:15:08

标签: redis load-balancing publish-subscribe health-monitoring horizontal-scaling

我有一台Redis服务器和多台Redis客户端。每个Redis客户端都是WebSocket + HTTP服务器,其中包括管理WebSocket连接。这些WebSocket + HTTP服务器隐藏在负载均衡器后面。

WebSocket + HTTP服务器提供GET /health HTTP端点。我希望此端点能够提供整个集群中当前WebSocket连接的总数。

当一个命中GET /health时,显然,负载均衡器会将请求分派给一个WebSocket + HTTP服务器实例。

如何创建一个WebSocket + HTTP服务器实例,询问所有其他实例当前管理的WebSocket连接数量是多少?

我想到了以下步骤:

  1. 该实例使用CLIENT LIST来了解当前有多少Redis客户端(例如n);
  2. 然后,实例将WEBSOCKET_CONNECTION_COUNT_REQUEST发布到Redis(假设所有Redis客户都订阅了此事件);
  3. 实例最终等待n WEBSOCKET_CONNECTION_COUNT_RESPONSE s,总结计数,然后通过HTTP返回。
  4. 您如何看待上述方法?难道它有点过于复杂吗?我觉得我可能有点过度工程......

    我最初认为实例可能INCR / DECR在Redis存储区内计数,但我不确定如何处理被杀死的实例(因为计数应该相应减少) )。我认为一个特别的解决方案会更好。尽管如此仍然持开放态度。

1 个答案:

答案 0 :(得分:1)

我使用排序集,其中成员是WS服务器ID,分数是他们上次" ping"的时间戳。

让每个WS" ping"通过用其id更新该排序集来定期(例如每10秒)。您可以使用Lua脚本从服务器获取时间并设置成员的分数以使一切变得美观和原子:

EVALSHA <script-sha1> 1 wsservers foo

因此,如果你的排序集被调用&#34; wsservers&#34;并且WS的id为foo,您可以在使用local t = redis.call('TIME') local live = redis.call('ZRANGE', KEYS[1], tonumber(t[0])-11, '+inf') redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', tonumber(t[0])-11) return #live 加载脚本后调用该脚本。

要返回计数,您需要做的就是在最后一个周期(即11秒)的有序集合上的范围并计算结果。您也可以利用这个机会修剪旧的死服务器。当然,Lua脚本是我的首选方法,这样做的任务都不需要实际将原始WS成员发送到调用客户端:

LIMIT 1