前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Go 语言社区】如何实现单服务器300万个长连接的?

【Go 语言社区】如何实现单服务器300万个长连接的?

作者头像
李海彬
发布2018-03-19 17:44:04
2.3K0
发布2018-03-19 17:44:04
举报
文章被收录于专栏:Golang语言社区Golang语言社区

不是吹牛,理论上完全可以达到。 (以下参考值皆是Linux平台上) 1,Linux单个进程可以维持的连接数(fd)理论值是通过ulimit -a设置,或在server内使用setrlimit()设置,具体最大是多少?我看我的64机上是64bits的一个数值,所以,权且认为理论上是2^64-1。 anyway,几百万不是问题。 2,TCP连接数。因为是Server端,不用向系统申请临时端口,只占fd资源。所以tcp连接数不受限制。 3,维持连接当然需要内存消耗,假如每个连接(fd),我们为其分配5k字节(应该足够了,就存放一些用户信息之类的)。这样是5k*3000000=15G。 文中有24G内存,应该也足够了。 ================================ 下面我们说下文中提及的 多消息循环、异步非阻塞。 先说异步和非阻塞吧。权且认为这俩是一个概念。都是指的IO的异步和非阻塞。 1,异步+非阻塞的话,Linux上必然是epoll了。 原理上简而言之吧,异步就是基于事件的读写,epoll同时监听所有的tcp连接(fd),当有哪些连接上有了事件(读、写、错误),就返回有事件的连接集合,然后处理这个集合里的需要处理的连接事件。这儿就是基于事件的异步IO。 非阻塞。 在得到有事件的tcp连接集合之后,逐一进行读(写)。分开来说,需要读的fd,其实数据已经到OS的tcp buffer里了,读完直接返回,CPU不等待。(返回EAGAIN,其实就进行了几次memcpy); 需要写的连接,同样,其实是把数据写到了OS的tcp buffer里,写满为止。。不会等待对方发来ACK再返回。这样,其实这里CPU基本上只进行了一些memcpy的操作。。即便同时几十万连接有事件,也是瞬间处理完的事。。。然后,CPU再进行异步io等待(epoll_wait())。 当然这儿要充分利用多核,最好将io线程和work线程分开。 2,多消息循环。。这个应该是他们内部的概念。我个人猜测是异步的消息协议。 举例子,传统的TCP连接是一问一答,如HTTP。

如图,客户端在发送A和发送B之间,CPU就纯等待。服务器在回复A之后,也是纯等待B包的到来。。这样的话。TCP吞吐量很低。 异步协议就是读写完全分开,无需等待(当然,在包内需要自行对应包的ID来识别对应请求包和回复包)。如图

这样的话,双方在任一时刻,都尽最大努力的发包。充分利用tcp连接。使单条TCP连接吞量直线上升。而且,如果其中有一个包处理的极慢,丝豪不影响其他包的回包。 大体推算一下流量,因为300万的客户端均是手机客户端,,假如每个人每天平均收到500条push信息。300万*500=1500000000, 1500000000 /一天86400=17361。一个封装的不错的server每秒进行2W次IO是很轻松的事。 最后说单台Hold大量和多台Hold小量的区别。 成本上肯定是多台的硬件本高了。。但是,这个量级,从架构上,绝对是多台更加合理。我们假如,每个连接有一个用户认证的过程 ,用户认证时要去数据库(或其他类似db)查询用户信息,当你升级服务重启时,300万用户瞬间断开,客户端会重连;再次启动之后,300万用户同时连接,同时请求库。。然后,杯具了。。。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档