V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
xuxu555
V2EX  ›  分享创造

Golang 需要异步吗

  •  1
     
  •   xuxu555 ·
    Allenxuxu · 2019-09-28 12:53:22 +08:00 · 6302 次点击
    这是一个创建于 1915 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前段时间,撸了个轮子 gev,主要就是基于 Reactor 模式的一个非阻塞 TCP 网络库,直接操作 epoll 和 kqueue,没有使用 net 标准库。

    优点就是快和内存占用低,缺点就是 issue 里这位大佬说的:

    go 使用协程+阻塞的模式来处理并发问题。这样的模式虽然对运行时要求很高,但对程序员却非常友好。这样的代码码也非常容易维护。 异步模式最大的问题就是回调嵌套,项目大了根本没法维护。我就是不想用回调方式写业务代码才转 go 的。 你认为这类 go 语言的异步框架有什么优势,要解决什么问题?

    Issue 里有一些讨论,肯定的、否定的都有。 Issue 链接: https://github.com/Allenxuxu/gev/issues/4

    个人觉得,这种异步库作为特殊场景的补充还是有价值的,内存占用低,速度也快,毕竟 Go 在 IOT 方面还是有很大希望的。也可能是因为我受 muduo 影响比较深,更加偏爱这种方式。。。

    想听听大家怎么看呢?

    第 1 条附言  ·  2019-09-28 14:22:51 +08:00

    GitHub 地址: https://github.com/Allenxuxu/gev

    吞吐量测试

    image

    详细信息,可以查看仓库 README https://github.com/Allenxuxu/gev

    22 条回复    2019-10-01 12:48:41 +08:00
    lhx2008
        1
    lhx2008  
       2019-09-28 12:58:51 +08:00 via Android
    跑分比原生用 channel 快多少?网络这边都是用的 epoll 吧,不相信有太大差别。
    xuxu555
        2
    xuxu555  
    OP
       2019-09-28 13:01:21 +08:00 via Android
    @lhx2008 ping pong 测试 吞吐量差好多,你可以点到 readme 里看看
    pubby
        3
    pubby  
       2019-09-28 13:08:30 +08:00
    内存占用测试数据呢?

    如果没有数量级的差距,我还是偏向加机器
    xuxu555
        4
    xuxu555  
    OP
       2019-09-28 13:09:55 +08:00 via Android
    @pubby 这个我觉得不需要测啊,一个协程大约 4k, 主要就是节约协程
    JRyan
        5
    JRyan  
       2019-09-28 13:25:25 +08:00
    如果考虑 goroutine 占用内存问题的话,可以考虑复用 goroutine,fasthttp 就是这么做的。
    xuxu555
        6
    xuxu555  
    OP
       2019-09-28 13:39:31 +08:00 via Android
    @JRyan go 都是阻塞读写,每个 tcp 连接都得分配两个 goroutine 给它。
    这个库是将 fd 注册到 epoll, 非阻塞读写
    JRyan
        7
    JRyan  
       2019-09-28 13:46:48 +08:00
    go 的底层实际也是非阻塞的,基于 epoll 的,只是代码写起来是阻塞的,你这个库测试看起来比原生的好,主要还是因为连接使用的 goroutine 少,调度少,消耗的资源少。
    xuxu555
        8
    xuxu555  
    OP
       2019-09-28 13:49:06 +08:00 via Android
    @JRyan 是的,go 在 goroutine 调度上是通过锁来实现的,但是开发者可以阻塞读写,代码容易理解和维护。
    linsijia1002
        9
    linsijia1002  
       2019-09-28 14:15:30 +08:00
    @JRyan go 底层是用 fd 阻塞读,不是用 epoll,你可以自己去看源码
    kidlj
        10
    kidlj  
       2019-09-28 14:21:13 +08:00
    sunny352787
        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
    sunny352787
        12
    sunny352787  
       2019-09-28 14:31:33 +08:00
    epoll 模式只在 linux 下能用,如果开发环境是 win 或者 mac 的话就没戏,只能另做封装
    xuxu555
        13
    xuxu555  
    OP
       2019-09-28 14:33:57 +08:00
    @sunny352787 库里面也对 mac 作了支持的,使用 kqueue,主要是为了开发调试方便, 毕竟服务器基本都是 linux
    sunny352787
        14
    sunny352787  
       2019-09-28 14:50:43 +08:00
    @xuxu555 对,问题就在这,相当于维护了多套底层,可能开发时候没问题生产环境就坏了,另外 win 下更麻烦,而且在 win 下写代码的还是更多吧
    sunny352787
        15
    sunny352787  
       2019-09-28 14:57:24 +08:00
    @xuxu555 所以还是我上面说的,看成本,如果成本合得上那当然可以,不过多数时候还是老老实实用同步模式比较好
    iPhoneXI
        16
    iPhoneXI  
       2019-09-28 15:01:28 +08:00 via Android
    @sunny352787 Python 3 asyncio 就支持了 Windows 下的 Proactor Ioloop,
    相信其他网络库也不难,看开发者精力了
    sunny352787
        17
    sunny352787  
       2019-09-28 15:18:46 +08:00
    @iPhoneXI 就问一个问题,楼主的代码你敢不敢用在生产环境,这个级别的项目如果我用的话我肯定会吃透再用,这就不只是开发者精力问题了,使用者也会消耗很多精力,所以作为技术储备可以试试,但上线用的话还要斟酌
    xuxu555
        18
    xuxu555  
    OP
       2019-09-28 17:03:08 +08:00
    @sunny352787 为了支持多套环境,维护多套底层是必然的,标准库底层不同系统也是不同的。( win 写后端不多吧,我见多大多用 mac,虽然我自己电脑是 win。。。。。虚拟机装 Ubuntu )
    xuxu555
        19
    xuxu555  
    OP
       2019-09-28 17:05:39 +08:00
    @iPhoneXI win 环境下,计划用 std net 实现下,保持对外接口一致就好了,开发能调试。(毕竟服务器大多数是 Linux )
    sunny352787
        20
    sunny352787  
       2019-09-29 13:49:33 +08:00
    @xuxu555 看规模多大咯,你这样做不是不可以,我一直说的是成本是不是合得上,正常开发一套东西用系统的同步方式处理简单出错又少,对开发人员要求也低,如果用你这一套的话就复杂很多,对开发人员要求也高。

    增加了系统复杂度不可避免的要增加开发时间,进而增加开发成本,所以如果不是非常必要,最好选择最简单的方案。

    但作为技术人员,对更复杂的技术的研究肯定是不可少的,所以我说作为技术储备没有任何问题,万一以后负载上来了总要有一个解决方案。
    xuxu555
        21
    xuxu555  
    OP
       2019-09-29 14:50:59 +08:00
    yulon
        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 异步读写文件不用另一套东西?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5215 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 03:49 · PVG 11:49 · LAX 19:49 · JFK 22:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.