Golang(27)-websocket进阶
source link: https://hongker.github.io/2021/04/22/golang-websocket-epoll/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Golang(27)-websocket进阶
之前有简单的介绍过websocket
的基本用法,本文将介绍在golang里如何处理大量websocket连接。
现在有一个即时通讯的需求,我们实现一个简单的websocket服务如下所示:
package main |
通过wscat -c localhost:8085
连接到websocket,并发送hello
和123
,得到测试结果如下:
> hello |
如果我们的服务需要面向100w个用户时,会发生什么情况?
1.每创建一个websocket连接,按照以上的实现方式,我们就需要创建一个goroutine来接收客户端的信息。一个goroutine大概需要2~8kb的内存
2.如果是同时有100万个连接,假设每个goroutine占用4kb内存,那么内存消耗大概在:4kb*1000000=4G。
光是保持连接,不做任何处理就已经消耗了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去监听的方案。
实现如下:
package main |
从上面的代码可以看到,我们只开启了两个gouroutine。一个负责监听epoll的就绪事件,一个负责处理websocket的消息。这样就能省下服务器的内存空间。
我在github上开源了一个websocket框架的项目,基于epoll模型和workerPool实现。想要了解更多的请查看: https://github.com/ebar-go/websocket
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK