V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
chenglus
V2EX  ›  问与答

websocket + redis pub/sub 做实时更新应该如何设计

  •  
  •   chenglus · 2020-07-15 20:56:30 +08:00 · 2036 次点击
    这是一个创建于 1593 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前我的结构是:

    1. 每个用户访问页面后会立即建立 websocket 长连接。

    2. 每个用户的 websocket 在连接建立时(on_open )会建立一个 redis connection,这个 redis connection 用来 subscribe 一个固定的 channel

    3. 当某个模型更改需要通知前端时,会用一个全局的 redis connection 来 publish 相关的内容到 channel 。

    4. 在第二步中订阅 channel 的回调会用 websocket 将更新的模型数据发给前端,前端实现实时更新。

    5. 用户离开页面后在触发 websocket 的 on_close 回调,回调中关闭用户 redis 链接。

    这种方案每个用户访问页面都会建立一个 redis 连接,而 redis 默认的最大链接数是 10000,也就是说在默认配置下页面最多承载 10000 左右个用户。想请教下各位大佬这种设计是否合理。

    15 条回复    2020-07-16 11:50:03 +08:00
    RickyHao
        1
    RickyHao  
       2020-07-15 21:16:32 +08:00 via Android
    不是,redis 连接不应该在后端用连接池维护吗?
    chenglus
        2
    chenglus  
    OP
       2020-07-15 21:24:53 +08:00
    @RickyHao redis 的 subscribe 是阻塞的,我目前是每个用户都起一个 redis 连接来 subscribe channel
    hly9469
        3
    hly9469  
       2020-07-15 21:26:35 +08:00 via iPhone
    webdis
    kaifang
        4
    kaifang  
       2020-07-15 21:31:03 +08:00
    之前做过类似的实验,不过用的是 mqtt + websocket 做的实时更新,用的是 emqx,号称百万级别连接,估计问题不大。
    RickyHao
        5
    RickyHao  
       2020-07-15 21:31:24 +08:00 via Android
    那你复用一个 sub 啊,通过内容里加标识来区分用户,然后后端做路由给各个 ws 连接
    swulling
        6
    swulling  
       2020-07-15 21:34:38 +08:00 via iPhone
    单机一万个用户还不够?
    chenglus
        7
    chenglus  
    OP
       2020-07-15 21:47:00 +08:00
    @kaifang 也是这种结构吗?一个用户对应一个 broker/subscriber
    chenglus
        8
    chenglus  
    OP
       2020-07-15 21:47:25 +08:00
    @swulling 只是想知道这种设计是否合理,有没有更好的方案
    chenglus
        9
    chenglus  
    OP
       2020-07-15 21:47:42 +08:00
    @RickyHao 感谢,我尝试一下
    huntcool001
        10
    huntcool001  
       2020-07-15 22:01:25 +08:00
    Redis pub/sub 几乎不具有实际使用意义. 因为消费者一旦掉线啥的,没消费到那个消息,那个消息就丢失了.


    用 Redis5.0 里面的 Stream 吧.

    还有一个方法是写个 Lua 脚本来当消费者,把订阅收到的信息存到某个 list 里. 实际消费者去 list 里消费. 因为 Lua 脚本存活在 Redis 服务器上,也就不存在掉线的问题了.
    h123123h
        11
    h123123h  
       2020-07-15 22:29:38 +08:00 via iPhone
    用 mq 把消息推送给 websocket chanel
    chihiro2014
        12
    chihiro2014  
       2020-07-15 22:34:02 +08:00
    Spring Reactor 了解下?
    chenglus
        13
    chenglus  
    OP
       2020-07-16 10:42:12 +08:00
    @huntcool001 感谢,粗略了解了下也支持多播,并且有 ack 确认机制保证不丢消息,应该可以被用来做 pusher
    sujin190
        14
    sujin190  
       2020-07-16 11:21:03 +08:00
    似乎这种短时页面上用的使用轮询机制感觉更简单的感觉,后台没过一段时间无数据超时就返回,有数据就返回数据,前端不延时,后台用个分布式锁啥的等待机制,需要返回的数据放到 redis 种,感觉结构更简单啊,直接 jquery ajax 就行,啥长连接啥心跳啥重试啥啥都不用管,容错啥的页更容易吧
    chenglus
        15
    chenglus  
    OP
       2020-07-16 11:50:03 +08:00
    @sujin190 我们是 web app,不是简单的页面,所以还是 websocket 更好些吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2951 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 13:10 · PVG 21:10 · LAX 05:10 · JFK 08:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.