之前有简单的介绍过websocket
的基本用法,本文将介绍在golang里如何处理大量websocket连接。
初阶
现在有一个即时通讯的需求,我们实现一个简单的websocket服务如下所示:
1 | package main |
通过wscat -c localhost:8085
连接到websocket,并发送hello
和123
,得到测试结果如下:
1 |
|
思考
如果我们的服务需要面向100w个用户时,会发生什么情况?
1 | 1.每创建一个websocket连接,按照以上的实现方式,我们就需要创建一个goroutine来接收客户端的信息。一个goroutine大概需要2~8kb的内存 |
光是保持连接,不做任何处理就已经消耗了4G的内存,还是挺恐怖的,所以下面开始介绍用epoll模型来解决这个问题。
Epoll
epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
Epoll提供了3个方法:Create、Ctl、Wait
- Create: 创建epoll句柄,返回文件标识符(fd)。
- Ctl: 根据epoll的fd,完成注册事件、删除事件、更新事件。
- Wait: 返回就绪事件。
我们可以通过epoll模型,来管理websocket连接,用来替代通过goroutine去监听的方案。
实现如下:
1 | package main |
从上面的代码可以看到,我们只开启了两个gouroutine。一个负责监听epoll的就绪事件,一个负责处理websocket的消息。这样就能省下服务器的内存空间。
拓展
我在github上开源了一个websocket框架的项目,基于epoll模型和workerPool实现。想要了解更多的请查看: https://github.com/ebar-go/websocket
- 本文作者: Hongker
- 本文链接: https://hongker.github.io/2021/04/22/golang-websocket-epoll/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!