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

如何在 1s 内广播消息到 30K 甚至更多的客户端?

  •  
  •   naquda · 2015-11-02 02:01:09 +08:00 · 5881 次点击
    这是一个创建于 3342 天前的主题,其中的信息可能已经有所发展或是发生改变。

    具体是这样的, 现在有个服务,是基于 JAVA Netty 的,
    有一个线程在不断产生数据,基本每一秒都会有新的数据,当这个数据产生后,需要尽快的发送到所有关心这个数据的客户端,对时间很敏感,最敏感的, 1S 内都要发送完。
    Netty 的话,我看用 ChannelGroup.write() 也没有并发的执行

    有什么样的方案可以做到这样的事情?
    查了一些资料,有些在 JAVA 上实现轻量级线程,比如 Quasar , 但具体应用资料很少。
    另外, Golang 是不是很容易干这种事情?

    26 条回复    2015-11-15 09:22:56 +08:00
    ritksm
        1
    ritksm  
       2015-11-02 02:42:47 +08:00
    MQ 消息 fanout
    naquda
        2
    naquda  
    OP
       2015-11-02 03:17:38 +08:00
    @ritksm 麻烦能否说得详细一点
    jedihy
        3
    jedihy  
       2015-11-02 03:27:31 +08:00
    如果你这里的广播不是指的 IP broadcast 的话, 1s 30K 有可能理论上都发不出去啊。你要计算一下消息大小 X 30K X 1s 是多少数据量,你的带宽够吗?实现的话,可以用非阻塞 IO 来发,搞 N 个进程,每个进程上跑一个非阻塞 IO 。把消息分发到这些进程然后让他们发送,把 CPU 和网卡资源利用满。
    naquda
        4
    naquda  
    OP
       2015-11-02 03:45:31 +08:00
    @jedihy 消息本身不大,一个消息 20byte 左右, 1S 30K ,带宽应该不是问题,但是这个消息时间敏感,需要尽快的发出去
    目前是这样的, 客户端会去主动去问服务端拿新的消息,这个消息在服务端,是由其他线程更新的(一个写, N 个读),但有时候,会刚好在消息被更新之前,拿到老的消息,导致客户端要再次不断去问服务器拿新的消息,现在 Netty 来处理这个并发是没问题的
    但我想,有么有可能服务端在消息更新的时候,主动发送到每个关心它的客户端,主要是要尽可能快的发送给所有客户端,
    用进程或者线程池来处理,还是很麻烦, 因为有不止一个消息,几乎没秒都有消息在更新,然后关心这个消息的客户端有多也有少,多的夸张点,有 30K , 少点也有几 K ,
    所有我找到有 JAVA 的轻量级线程实现比如 Quasar , 但,我还不知道可不可以,以及怎么和 NETTY 一起用
    patrickstar
        5
    patrickstar  
       2015-11-02 08:07:31 +08:00
    如果不能多播估计是不现实的, java 不懂,看看你采用的中间件的能力
    chinawrj
        6
    chinawrj  
       2015-11-02 08:09:49 +08:00
    @naquda 只要消息小于 1K ,对于网卡的负载影响不是很大吧。反正你要一秒内发送 30K 个 skb_buf 。先用 C 语言写个微型 TCP server ,然后用 30K 的客户端测试一下。看看能不能搞定这个事情。也就半天就能写好的事情。目测一般服务器搞不定
    beneo
        7
    beneo  
       2015-11-02 08:24:35 +08:00
    消息中间件不就是干这个的么?非要自己写?
    beneo
        8
    beneo  
       2015-11-02 08:24:58 +08:00
    rabbitmq
    fsneak
        9
    fsneak  
       2015-11-02 08:34:36 +08:00 via iPhone
    嗯…虽然我不是很熟悉…不过 netty 的线程模型应该是每个客户端连接的读写都是单线程的,每个线程处理多个连接,有多个这样的线程吧?既然最底层是这样,那再在上层考虑并发应该没啥意思吧…?
    AstroProfundis
        10
    AstroProfundis  
       2015-11-02 08:48:22 +08:00
    这样的需求应该搞个消息中间件...典型场景...
    yghack
        11
    yghack  
       2015-11-02 08:53:24 +08:00
    单服务器搞不定的。
    master13
        12
    master13  
       2015-11-02 08:56:38 +08:00
    把客户端的名字改为“ 30K ”,然后 1 秒钟发给他......
    lhbc
        13
    lhbc  
       2015-11-02 09:20:04 +08:00 via iPhone
    用 UDP ,不要用 TCP
    你的消息只有 20 Byte ,但是加上 TCP 握手等开销,流量多了好几倍。

    随便一个高级语言都能搞定。
    ixiaohei
        14
    ixiaohei  
       2015-11-02 09:30:42 +08:00
    赶紧 1 秒钟单机干不了
    ixiaohei
        15
    ixiaohei  
       2015-11-02 09:30:56 +08:00
    感觉 打错了
    ruosu0710
        16
    ruosu0710  
       2015-11-02 09:58:41 +08:00
    用一楼的 MQ 方式:ActiveMQ 或者 RabbitMQ Topic 模式
    SparkMan
        17
    SparkMan  
       2015-11-02 12:39:06 +08:00
    推荐使用 ZeroMq (“史上最快的消息队列”),用发布订阅模型。跟上面说的 ActiveMQ 或者 RabbitMQ 完全不同,他俩的速度肯定跟不上; ZeroMQ 不能持久化,但是特别快,是要取代 socket 的
    SparkMan
        18
    SparkMan  
       2015-11-02 12:40:52 +08:00
    ActiveMQ 或者 RabbitMQ 之所以觉得慢,是因为跟 Kafka 比要慢很多,所以推荐你用 ZeroMQ
    Comdex
        19
    Comdex  
       2015-11-02 12:55:42 +08:00
    golang 的 nsq
    naquda
        20
    naquda  
    OP
       2015-11-02 17:20:35 +08:00
    谢谢各位, 先研究一下各位提供的方案
    znoodl
        21
    znoodl  
       2015-11-02 17:45:16 +08:00 via iPhone
    zeromq push pull
    znoodl
        22
    znoodl  
       2015-11-02 17:45:59 +08:00 via iPhone
    错了 pub sub
    anexplore
        23
    anexplore  
       2015-11-02 18:13:55 +08:00
    @SparkMan 能否分享一下 rabbitmq 比 kafka 慢很多的场景?我以前做过 2 组测试,消息大小分别为 1k 与 40kb 的时候, rabbitmq 与 kafka ( batch 设为 100 )性能不相上下。
    naquda
        24
    naquda  
    OP
       2015-11-02 18:15:15 +08:00
    研究了下 ZeroMQ , 目前还很难用上这些技术, 主要是因为这个客户端也要做相应的修改,而我这的客户端比较特殊,并不是 X86 平台, PORTING 这些库,带来更多的未知风险, 所以还是要在传统的 SOCKET 上实现
    pkking
        25
    pkking  
       2015-11-02 18:16:11 +08:00
    socket 中的广播或者多播可以满足你
    ncisoft
        26
    ncisoft  
       2015-11-15 09:22:56 +08:00 via Android
    @pkking +1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2996 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:34 · PVG 22:34 · LAX 06:34 · JFK 09:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.