Go 进阶 · 分布式爬虫实战
郑建勋
Go 语言技术专家,《Go 语言底层原理剖析》作者
15839 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 58 讲
Go 进阶 · 分布式爬虫实战
15
15
1.0x
00:00/00:00
登录|注册

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
立即购买
登录 后留言

全部留言(17)

  • 最新
  • 精选
  • c
    基础不好 看着有点懵逼

    作者回复: 我还以为已经讲得很简单了哦,哪里不太懂可以提出来哈 。问题导向+循序渐进,顺着我这个思路也可以查漏补缺哈

    2022-10-25归属地:北京
    3
    5
  • 范飞扬
    “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_a98e22
    netpoll不是字节开发的网络框架吗

    作者回复: 不是哦,你可能记错了

    2022-12-18归属地:四川
  • 那时刻
    网络 IO 能够用异步化的事件驱动的方式来管理,磁盘 IO 则不行. 网络 IO 的socket 的句柄实现了 .poll 方法,可以用 epoll 池来管理. 文件 IO 的 read/write 都是同步的 IO ,没有实现 .poll 所以也用不了 epoll 池来监控读写事件,所以磁盘 IO 的完成只能同步等待。
    2022-11-01归属地:北京
    1
    11
  • Elroy
    Go1.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
收起评论
显示
设置
留言
17
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部