前段时间,撸了个轮子 gev,主要就是基于 Reactor 模式的一个非阻塞 TCP 网络库,直接操作 epoll 和 kqueue,没有使用 net 标准库。
优点就是快和内存占用低,缺点就是 issue 里这位大佬说的:
go 使用协程+阻塞的模式来处理并发问题。这样的模式虽然对运行时要求很高,但对程序员却非常友好。这样的代码码也非常容易维护。 异步模式最大的问题就是回调嵌套,项目大了根本没法维护。我就是不想用回调方式写业务代码才转 go 的。 你认为这类 go 语言的异步框架有什么优势,要解决什么问题?
Issue 里有一些讨论,肯定的、否定的都有。 Issue 链接: https://github.com/Allenxuxu/gev/issues/4
个人觉得,这种异步库作为特殊场景的补充还是有价值的,内存占用低,速度也快,毕竟 Go 在 IOT 方面还是有很大希望的。也可能是因为我受 muduo 影响比较深,更加偏爱这种方式。。。
想听听大家怎么看呢?
GitHub 地址: https://github.com/Allenxuxu/gev
吞吐量测试
详细信息,可以查看仓库 README https://github.com/Allenxuxu/gev
1
lhx2008 2019-09-28 12:58:51 +08:00 via Android
跑分比原生用 channel 快多少?网络这边都是用的 epoll 吧,不相信有太大差别。
|
3
pubby 2019-09-28 13:08:30 +08:00
内存占用测试数据呢?
如果没有数量级的差距,我还是偏向加机器 |
5
JRyan 2019-09-28 13:25:25 +08:00
如果考虑 goroutine 占用内存问题的话,可以考虑复用 goroutine,fasthttp 就是这么做的。
|
6
xuxu555 OP @JRyan go 都是阻塞读写,每个 tcp 连接都得分配两个 goroutine 给它。
这个库是将 fd 注册到 epoll, 非阻塞读写 |
7
JRyan 2019-09-28 13:46:48 +08:00
go 的底层实际也是非阻塞的,基于 epoll 的,只是代码写起来是阻塞的,你这个库测试看起来比原生的好,主要还是因为连接使用的 goroutine 少,调度少,消耗的资源少。
|
8
xuxu555 OP @JRyan 是的,go 在 goroutine 调度上是通过锁来实现的,但是开发者可以阻塞读写,代码容易理解和维护。
|
9
linsijia1002 2019-09-28 14:15:30 +08:00
@JRyan go 底层是用 fd 阻塞读,不是用 epoll,你可以自己去看源码
|
10
kidlj 2019-09-28 14:21:13 +08:00
|
11
sunny352787 2019-09-28 14:27:46 +08:00 1
看成本,是加程序员便宜还是加机器便宜,不过作为技术储备可以玩玩
顺便,贴俩 github 地址 https://github.com/smallnest/1m-go-tcp-server https://github.com/eranyanay/1m-go-websockets |
12
sunny352787 2019-09-28 14:31:33 +08:00
epoll 模式只在 linux 下能用,如果开发环境是 win 或者 mac 的话就没戏,只能另做封装
|
13
xuxu555 OP @sunny352787 库里面也对 mac 作了支持的,使用 kqueue,主要是为了开发调试方便, 毕竟服务器基本都是 linux
|
14
sunny352787 2019-09-28 14:50:43 +08:00
@xuxu555 对,问题就在这,相当于维护了多套底层,可能开发时候没问题生产环境就坏了,另外 win 下更麻烦,而且在 win 下写代码的还是更多吧
|
15
sunny352787 2019-09-28 14:57:24 +08:00
@xuxu555 所以还是我上面说的,看成本,如果成本合得上那当然可以,不过多数时候还是老老实实用同步模式比较好
|
16
iPhoneXI 2019-09-28 15:01:28 +08:00 via Android
@sunny352787 Python 3 asyncio 就支持了 Windows 下的 Proactor Ioloop,
相信其他网络库也不难,看开发者精力了 |
17
sunny352787 2019-09-28 15:18:46 +08:00
@iPhoneXI 就问一个问题,楼主的代码你敢不敢用在生产环境,这个级别的项目如果我用的话我肯定会吃透再用,这就不只是开发者精力问题了,使用者也会消耗很多精力,所以作为技术储备可以试试,但上线用的话还要斟酌
|
18
xuxu555 OP @sunny352787 为了支持多套环境,维护多套底层是必然的,标准库底层不同系统也是不同的。( win 写后端不多吧,我见多大多用 mac,虽然我自己电脑是 win。。。。。虚拟机装 Ubuntu )
|
19
xuxu555 OP @iPhoneXI win 环境下,计划用 std net 实现下,保持对外接口一致就好了,开发能调试。(毕竟服务器大多数是 Linux )
|
20
sunny352787 2019-09-29 13:49:33 +08:00
@xuxu555 看规模多大咯,你这样做不是不可以,我一直说的是成本是不是合得上,正常开发一套东西用系统的同步方式处理简单出错又少,对开发人员要求也低,如果用你这一套的话就复杂很多,对开发人员要求也高。
增加了系统复杂度不可避免的要增加开发时间,进而增加开发成本,所以如果不是非常必要,最好选择最简单的方案。 但作为技术人员,对更复杂的技术的研究肯定是不可少的,所以我说作为技术储备没有任何问题,万一以后负载上来了总要有一个解决方案。 |
21
xuxu555 OP @sunny352787 👍
|
22
yulon 2019-10-01 12:48:41 +08:00
楼上们真的信手拈来,不看源码在那空想:
https://github.com/golang/go/blob/master/src/runtime/netpoll_epoll.go https://github.com/golang/go/blob/master/src/runtime/netpoll_windows.go https://github.com/golang/go/blob/master/src/runtime/netpoll_kqueue.go https://github.com/golang/go/blob/master/src/runtime/netpoll_aix.go https://github.com/golang/go/blob/master/src/runtime/netpoll_solaris.go Linux epoll、Windows IOCP、macOS kqueue,你们想到的想不到的,写 Go 的那群老人精会想不到? 「而且在 win 下写代码的还是更多吧」?你说 epoll 细分之后效率高没问题,IOCP 不比 epoll 简单? epoll 还只支持网络呢,Linux 异步读写文件不用另一套东西? |