首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
inktiger
V2EX  ›  Java

思考个问题, Java 如何通过 websocket 和 RabbitMq 集群实现复杂聊天系统呢

  •  
  •   inktiger · 38 天前 · 1295 次点击
    这是一个创建于 38 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网上看到的方案貌似都是用 redis 队列 /订阅或者 mq 队列来实现集群的,那么假如有 10 台服务器,使用 webscoket 和 RabbitMq 来实现集群间的消息发送,用户和连接的服务器关系保存在 redis,那么某一个用户发送消息是否就代表着群里有多少人就需要查询多少次 redis 获取到其他在线用户所在服务器依次给其他用户发送消息呢?这样是否太夸张了,消息在于实时性,单单一个用户发一条消息就要这么折腾 redis,如果多了是否就扛不住了

    20 条回复    2020-06-03 15:43:23 +08:00
    Austaras
        1
    Austaras   38 天前
    别问,问就是用 elixir
    wellsc
        2
    wellsc   38 天前
    用 Akka
    guyeu
        3
    guyeu   38 天前
    emmmm redis 有键空间通知和键事件通知来避免你说的这种情况。。。
    inktiger
        4
    inktiger   38 天前
    @guyeu 额,感觉用这个的好少
    inktiger
        5
    inktiger   38 天前
    @wellsc 这么冷门的东西么。。。
    opengps
        6
    opengps   38 天前
    大部分人对于大型系统的理解,中间件成了必不可少,完全错了,中间件只是为了解耦合和提高吞吐!
    如果你的 socket 服务端可以做到精确命中目标连接所在服务器然后转发,那么 mq 这一层显然必要性就不高了,毕竟你只有 10 台机器的压力负载
    guyeu
        7
    guyeu   38 天前
    @inktiger #4 这个东西有一些限制,具体用起来也不像消息队列那种订阅 /推送的模式舒服,各种客户端的支持也不见得好。但它确实能解决你提出的那个问题。
    shenjixiang
        8
    shenjixiang   38 天前
    @opengps 不用 mq 队列,那怎么保证消息先后到达的顺序呢?
    shenjixiang
        9
    shenjixiang   38 天前
    lz 提出的这个问题完全是数据结构的设计问题。。
    opengps
        10
    opengps   38 天前
    @shenjixiang 你用了 mq 也仅仅是对到达服务器的顺序做了个强制排序而已。
    我做过类似聊天业务,回想下业务场景,一对一私聊,0.1 秒的时差就已经足够对消息排序了。即使把并发考虑到钉钉那种 5000 人大群的规模,用微秒本身去排序也没啥大问题的,因为同一微秒的消息即使乱序,也已经不会对群消息造成直接影响了(网络因素本身就已经不能让消息不是微秒级别都准确了)
    inktiger
        11
    inktiger   38 天前
    @opengps 其实 mq 也有一个作用就是定位到消息推送到长连接所在用户的那一台服务器
    nwljy
        12
    nwljy   38 天前
    RocketMQ 自身可以支持 webscoket ( Kafka )
    opengps
        13
    opengps   38 天前
    @inktiger 是的,达到业务效果怎么着都行。我最早的交换通信就是只用 memcached 全局共享存下所有公网连接信息,然后各个服务器收到消息通过 memcached 找准服务器,然后内网用短链接精准转发消息
    opengps
        14
    opengps   38 天前
    @nwljy 虽然可以,但是这个功能你不会真敢用在公网吧? im 通信一定得用一套自己的通信协议来实现数据加密的
    qinxi
        15
    qinxi   38 天前
    每个集群节点订阅自己的 $ip_$port_quenename, 自己 redis 维护一份 用户连接所在服务器所订阅的队列名. ,需要给他发消息,就发到对应服务器的队列
    tairan2006
        16
    tairan2006   38 天前 via Android
    直接用 mqtt 不就完了
    inktiger
        17
    inktiger   38 天前
    @qinxi 其实我就是这么做的,但是如果有群发的情况,当用户都分布在不同服务器的时候,你就得去挨个读取用户的所在服务器,我就在想这样会不会量大的时候读不过来
    yyConstantine
        18
    yyConstantine   38 天前
    @inktiger 简单粗暴一点直接广播消费呢?
    inktiger
        19
    inktiger   38 天前
    @yyConstantine 广播消费的话太浪费资源了,还是精准推送节约点
    ljzxloaf
        20
    ljzxloaf   37 天前
    用户建立连接时,查看当前服务器是否已经订阅了该用户所属的所有群的 queue,没有的话去订阅;连接关闭时,就像引用计数一样,判断下哪些 queue 已经用不到了,取消订阅。

    没做过,纯脑洞。感觉这样的话建立连接和关闭连接的开销也不小。。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2664 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:31 · PVG 13:31 · LAX 22:31 · JFK 01:31
    ♥ Do have faith in what you're doing.