百万 Go TCP 连接的思考: 正常连接下的吞吐率和延迟

栏目: 服务器 · 发布时间: 5年前

内容简介:这一篇文章介绍了I/O密集型服务器和计算密集型的服务器的两种场景,对多epoller服务器和goroutine-per-connection服务器两种服务器进行测试,连接数分别是5000、2000、1000、500、200和100。第一篇第二篇

这一篇文章介绍了I/O密集型服务器和计算密集型的服务器的两种场景,对多epoller服务器和goroutine-per-connection服务器两种服务器进行测试,连接数分别是5000、2000、1000、500、200和100。

第一篇 百万 Go TCP 连接的思考: epoll方式减少资源占用

第二篇 百万 Go TCP 连接的思考2: 百万连接的吞吐率和延迟

第三篇 百万 Go TCP 连接的思考: 正常连接下的吞吐率和延迟

相关代码已发布到github上: 1m-go-tcp-server

前两篇的是有巨量连接的情况下服务器的性能,这类服务器可能应用于消息推送、IOT、页游等场景,追求的是大量连接,并发量相对不大的场景。还有一类场景是服务器的连接数不多,几十几百,最多几千的TCP连接,比如公司内的服务之间的调用等,这类服务器在不同的实现下的性能是怎样的?

测试区分两个场景: I/O密集型和计算密集型。I/O密集型的服务比如文件的读取、数据库的访问,远程服务的调用等等,计算密集型的访问比如区块链的挖矿、算法的计算、类似 redis 这样的基于内存的数据处理服务等等(当然redis还是memory bound类型的服务)。

我们通过 time.Sleep 让goroutine休眠来模拟I/O密集型的服务,实际goroutine休眠和真正的I/O密集型的服务还是有区别的,虽然它们都有一定的耗时,goroutine在等待的过程中会休眠,但是I/O密集型还有大量的I/O访问,比如磁盘、网络等等。出于方便测试的目的,我们还是使用 time.Sleep 来模拟,主要测试goroutine在休眠一段时间后对性能的影响。

计算密集型的访问我们采用挖矿算法,通过计算hash值,满足一定的挖矿难度让CPU进行大量的计算动作。

测试分别采用并发连接数为 5000、2000、1000、500、200、100,测试对应的吞吐率和延迟。

测试使用多epoller的方式实现的服务器和goroutine-per-connection实现的服务器。因为连接数少,我们可以采用goroutine-per-connection的方式。

九、 I/O 密集型的服务器(无sleep)

首先测试I/O密集型的服务器,在没有sleep的情况下,两个服务器的数据对比如下:

多epoller服务器

代码: 10_io_intensive_epoll_server

5000 2000 1000 500 200 100
tps 210064 203027 207097 208460 200798 212587
latency(s) 23.2 9.1 4.5 2.3 0.9 0.5

吞吐率变化不大,基本都在误差以内,延迟随着连接数的降低而降低,基本成线性关系。

服务器可以达到20万的吞吐率。

goroutine-per-connection 服务器

代码: 11_io_intensive_goroutine

5000 2000 1000 500 200 100
tps 203038 208002 209128 207990 209192 212376
latency(s) 24 9.2 4.6 2.3 0.9 0.5

可以看到,当服务器的业务简单,基本没有耗时的情况下,这两种实现的差别不大,基本一样。

十、 I/O 密集型的服务器 (sleep 10 ms)

我们模拟I/O耗时10毫秒的情况,两个服务器的数据对比如下:

多epoller服务器

5000 2000 1000 500 200 100
tps 6218 6256 6251 6108 6027 4736
latency(s) 0.8 0.3 0.2 0.08 0.04 0.03

吞吐率急剧下降。

goroutine-per-connection 服务器

5000 2000 1000 500 200 100
tps 203088 194783 98895 49326 19747 9886
latency(s) 0.02 0.01 0.01 0.01 0.01 0.01

可以看懂吞吐率会和连接数相关,但是也不是线性关系,随着连接数的增加,所带来的吞吐率收益也慢慢的变弱,也就是有一个拐点,连接数的增加带来的吞吐率的增加将变得很小。

看它的延迟时间,连接数2000以下延迟就是都是业务所耗费的时间(10毫米)。

这给了我们一个启示,在连接数比较小的情况下,正统的goroutine-per-connection可以取得很好的延迟,并且为了提高吞吐率,我们可以适当增加连接数。

十一、 计算密集型服务器

采用挖矿算法,计算哈希值,如果哈希值的前12bit都是0的话算挖矿成功。

多epoller服务器

代码: 12_cpu_intensive_epoll_server

5000 2000 1000 500 200 100
tps 212554 227291 224509 229796 226687 226147
latency(s) 0.02 0.01 0.004 0.002 0.001 0.0005

吞吐率基本不变,但是延迟随着连接数的降低而成线性降低。

goroutine-per-connection 服务器

代码: 13_cpu_intensive_goroutine

5000 2000 1000 500 200 100
tps 211048 212343 228978 228756 228768 229425
latency(s) 0.02 0.01 0.005 0.002 0.001 0.0005

吞吐率和多epoller方式基本一致,延迟也一样。 可以看出对于计算密集型的服务,这两种方式的性能差别不大。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning Python, 5th Edition

Learning Python, 5th Edition

Mark Lutz / O'Reilly Media / 2013-7-6 / USD 64.99

If you want to write efficient, high-quality code that's easily integrated with other languages and tools, this hands-on book will help you be productive with Python quickly. Learning Python, Fifth Ed......一起来看看 《Learning Python, 5th Edition》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具