07|冰川之下:深入Go高并发网络模型
郑建勋
你好,我是郑建勋。
很多人认为,Go 语言是开发网络服务的极佳选择。因为开发者能够简单、高效地处理大量的并发请求。
之所以说 Go 语言开发简单,是因为 Go 是以同步的方式来处理网络 I/O 的,它会等待网络 I/O 就绪后,才继续下面的流程,这是符合开发者直觉的处理方式。说 Go 语言高效,是因为在同步处理的表象下,Go 运行时封装 I/O 多路复用,灵巧调度协程,实现了异步的处理,也实现了对 CPU 等资源的充分利用。这节课,我们就深入看看 Go 是如何做到这一点的。
首先,让我们循序渐进地从几个重要的概念,阻塞与非阻塞、文件描述符与 Socket 说起。
阻塞与非阻塞
程序在运行过程中,要么在执行,要么在等待执行(陷入到阻塞的状态)。如果当前程序处理的时间大多数花在 CPU 上,它就是 CPU 密集型(CPU-bound)系统。相反,如果程序的大多数时间花费在等待 I/O 上,这种程序就是 I/O 密集型(I/O bound)的。
很多网络服务属于 I/O 密集型系统,因为它们把大量时间花费在了网络请求上。如果后续的处理流程需要依赖网络 I/O 返回的数据,那么当前的任务就要陷入到堵塞状态中。然而,很多情况下我们并不希望当前任务的堵塞会影响到其他任务的执行,我们希望充分利用 CPU 资源,承载更多的请求量和更快的响应速度。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
Go语言以其简单高效的并发处理能力成为开发网络服务的优选语言。本文深入探讨了Go语言在高并发网络模型中的应用和实现原理。文章首先介绍了阻塞与非阻塞的概念,以及文件描述符与Socket的作用。随后详细解释了五种I/O模型,包括阻塞I/O、非阻塞I/O、多路复用I/O、信号驱动I/O和异步I/O。特别强调了Go语言采用的I/O多路复用 + 非阻塞I/O + 协程的不寻常方式构建网络模型。文章还介绍了Reactor网络模型及其变体,以及在Linux平台上应用的情况。通过对协程、同步编程模式和多路复用的深入讨论,阐明了Go语言网络模型的优势。总的来说,Go语言的成功法宝可以总结为同步编程+多路复用+非阻塞I/O+协程调度。这种模式简单直接,符合开发者的直觉,同时能够轻松地创建大量协程。在高并发网络I/O密集的环境下,Go调度器牢牢地锁定了协程的控制权,保证了程序的高性能。文章通过深入的技术讲解,帮助读者快速了解Go语言在高并发网络模型中的应用和实现原理。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 进阶 · 分布式爬虫实战》,新⼈⾸单¥68
《Go 进阶 · 分布式爬虫实战》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(17)
- 最新
- 精选
- c基础不好 看着有点懵逼
作者回复: 我还以为已经讲得很简单了哦,哪里不太懂可以提出来哈 。问题导向+循序渐进,顺着我这个思路也可以查漏补缺哈
2022-10-25归属地:北京35 - 范飞扬“Go 则采取了一种不太寻常的方式来构建自己的网络模型,我们可以将其理解为 I/O 多路复用 + 非阻塞 I/O + 协程。” I/O 多路复用 和 非阻塞 I/O 不是两个IO模型吗?这两个不是互斥吗?怎么两个同时都有?
作者回复: 非阻塞是对线程不阻塞,但实际上协程是阻塞了,但是协程这种阻塞很轻量级。 我们要解决协程阻塞时等待多个socket的问题,这就涉及到多路复用了
2022-11-04归属地:北京4 - 请务必优秀催更
作者回复: copy that
2022-10-26归属地:北京3 - 范飞扬我还是很疑惑,哪来的非阻塞IO?网络到内核这一步?内核到应用程序这一步?
作者回复: 非阻塞IO指的是对线程不阻塞,这是通过在创建socket时候,传递了一个socket不阻塞的标识,这时操作系统的socket API不会阻塞线程,而是立即返回
2022-12-01归属地:北京2 - 文经今天的这讲很有收获,看到Go网络处理的全局图和底层原理,我之前看http库的源码时懵懵懂懂的,知道了自己差缺补漏的方向了:Go协程的调度和《Unix网络编程》第一卷翻出来看一看。 想请教郑老师的是:看样子Go已经将网络处理到极致了,还有什么优化的方向吗?
作者回复: 没有最好的,只有最适合的。Go的网络处理由于每一次都会新开辟协程,在极致的场景下,仍然会有瓶颈
2022-11-26归属地:广东1 - 马里奥作者写的很好 我都看入迷了 就是想问问啥时候能全部更新完 看着不过瘾
作者回复: 哈哈
2022-11-14归属地:北京1 - Geek_a98e22netpoll不是字节开发的网络框架吗
作者回复: 不是哦,你可能记错了
2022-12-18归属地:四川 - 那时刻网络 IO 能够用异步化的事件驱动的方式来管理,磁盘 IO 则不行. 网络 IO 的socket 的句柄实现了 .poll 方法,可以用 epoll 池来管理. 文件 IO 的 read/write 都是同步的 IO ,没有实现 .poll 所以也用不了 epoll 池来监控读写事件,所以磁盘 IO 的完成只能同步等待。2022-11-01归属地:北京111
- ElroyGo1.9增加了针对文件 I/O 的 poller 功能,类似 netpoller,但是常规文件不支持 pollable,一旦阻塞,线程(M)将挂起。2022-10-25归属地:北京7
- 温雅小公子磁盘I/O:对于磁盘I/O,Go采用的是同步阻塞式的I/O处理方式。在进行磁盘I/O操作时,Go会将当前的goroutine(协程)阻塞,直到I/O操作完成。这种方式在处理文件读写、数据库访问等操作时非常有效。 网络I/O:对于网络I/O,Go采用的是异步非阻塞式的I/O处理方式。在进行网络I/O操作时,Go会使用goroutine和非阻塞I/O等技术,使得I/O操作可以在后台进行,而不会阻塞当前的goroutine。这种方式在处理网络通信、HTTP请求等操作时非常有效,可以充分利用CPU资源,提高并发性能。2023-05-08归属地:中国台湾3
收起评论