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

2015-11-02 02:01:09 +08:00
 naquda

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

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

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

随便一个高级语言都能搞定。
ixiaohei
2015-11-02 09:30:42 +08:00
赶紧 1 秒钟单机干不了
ixiaohei
2015-11-02 09:30:56 +08:00
感觉 打错了
ruosu0710
2015-11-02 09:58:41 +08:00
用一楼的 MQ 方式:ActiveMQ 或者 RabbitMQ Topic 模式
SparkMan
2015-11-02 12:39:06 +08:00
推荐使用 ZeroMq (“史上最快的消息队列”),用发布订阅模型。跟上面说的 ActiveMQ 或者 RabbitMQ 完全不同,他俩的速度肯定跟不上; ZeroMQ 不能持久化,但是特别快,是要取代 socket 的
SparkMan
2015-11-02 12:40:52 +08:00
ActiveMQ 或者 RabbitMQ 之所以觉得慢,是因为跟 Kafka 比要慢很多,所以推荐你用 ZeroMQ
Comdex
2015-11-02 12:55:42 +08:00
golang 的 nsq
naquda
2015-11-02 17:20:35 +08:00
谢谢各位, 先研究一下各位提供的方案

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/232793

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX