golang http server

61 阅读1分钟

曾经在面试一家餐饮互联网公司的时候聊到 golang 标准库的 http server,含糊地提到 golang 底层会使用操作系统的多路复用,比如 linux 下会用到 epoll,突然被面试官一脸嫌弃地打断“golang http 底层没有使用 epoll!”,时隔良久依然记忆犹新,今天闲来无事再来探究一下这个问题。

  • golang 网络轮询器

之所以会这么回答,是因为先前看到过 draveness 大佬的这篇博客。里面有描述 golang 在网络 I/O 和文件 I/O 时都会用到网络轮询器,「它利用了操作系统提供的 I/O 多路复用模型来提升 I/O 设备的利用率以及程序的性能」。其中还讲解了其实现原理,但没有提到具体什么时机会启动这个网络轮询器,不过稍加查询就可以找到,这篇博客讲解了 net.Listen 方法会注册 fd 到网络轮询器。

  • 另一种 epoll

有趣的是我依稀记得有人在 golang 下直接写过 epoll 调用,然后竟然又找到了这篇博客,发现他是使用 golang 的 net 库获取到 connection,然后用自己封装的 golang 提供的 sys 库中的 epoll 来进行 I/O,目的是在超大量连接场景下减少因 goroutine 过多造成的内存和 CPU 开销。

  • why

其实纵观 golang 的 features,不难理解为啥会有「网络轮询器」,其开发者在底层提供很多常用的优化给普通研发人员,例如 GC、goroutine,让 go 代码写出来显得简洁而优雅(当然,其实很多时候也不简洁[doge])。