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

Golang 需要异步吗

  •  1
     
  •   xuxu555 · 72 天前 · 3724 次点击
    这是一个创建于 72 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    想听听大家怎么看呢?

    第 1 条附言  ·  72 天前

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

    吞吐量测试

    image

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

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

    如果没有数量级的差距,我还是偏向加机器
        4
    xuxu555   72 天前 via Android
    @pubby 这个我觉得不需要测啊,一个协程大约 4k, 主要就是节约协程
        5
    JRyan   72 天前
    如果考虑 goroutine 占用内存问题的话,可以考虑复用 goroutine,fasthttp 就是这么做的。
        6
    xuxu555   72 天前 via Android
    @JRyan go 都是阻塞读写,每个 tcp 连接都得分配两个 goroutine 给它。
    这个库是将 fd 注册到 epoll, 非阻塞读写
        7
    JRyan   72 天前
    go 的底层实际也是非阻塞的,基于 epoll 的,只是代码写起来是阻塞的,你这个库测试看起来比原生的好,主要还是因为连接使用的 goroutine 少,调度少,消耗的资源少。
        8
    xuxu555   72 天前 via Android
    @JRyan 是的,go 在 goroutine 调度上是通过锁来实现的,但是开发者可以阻塞读写,代码容易理解和维护。
        9
    linsijia1002   72 天前
    @JRyan go 底层是用 fd 阻塞读,不是用 epoll,你可以自己去看源码
        11
    sunny352787   72 天前   ♥ 1
    看成本,是加程序员便宜还是加机器便宜,不过作为技术储备可以玩玩

    顺便,贴俩 github 地址
    https://github.com/smallnest/1m-go-tcp-server
    https://github.com/eranyanay/1m-go-websockets
        12
    sunny352787   72 天前
    epoll 模式只在 linux 下能用,如果开发环境是 win 或者 mac 的话就没戏,只能另做封装
        13
    xuxu555   72 天前
    @sunny352787 库里面也对 mac 作了支持的,使用 kqueue,主要是为了开发调试方便, 毕竟服务器基本都是 linux
        14
    sunny352787   72 天前
    @xuxu555 对,问题就在这,相当于维护了多套底层,可能开发时候没问题生产环境就坏了,另外 win 下更麻烦,而且在 win 下写代码的还是更多吧
        15
    sunny352787   72 天前
    @xuxu555 所以还是我上面说的,看成本,如果成本合得上那当然可以,不过多数时候还是老老实实用同步模式比较好
        16
    iPhoneXI   72 天前 via Android
    @sunny352787 Python 3 asyncio 就支持了 Windows 下的 Proactor Ioloop,
    相信其他网络库也不难,看开发者精力了
        17
    sunny352787   72 天前
    @iPhoneXI 就问一个问题,楼主的代码你敢不敢用在生产环境,这个级别的项目如果我用的话我肯定会吃透再用,这就不只是开发者精力问题了,使用者也会消耗很多精力,所以作为技术储备可以试试,但上线用的话还要斟酌
        18
    xuxu555   72 天前
    @sunny352787 为了支持多套环境,维护多套底层是必然的,标准库底层不同系统也是不同的。( win 写后端不多吧,我见多大多用 mac,虽然我自己电脑是 win。。。。。虚拟机装 Ubuntu )
        19
    xuxu555   72 天前
    @iPhoneXI win 环境下,计划用 std net 实现下,保持对外接口一致就好了,开发能调试。(毕竟服务器大多数是 Linux )
        20
    sunny352787   71 天前
    @xuxu555 看规模多大咯,你这样做不是不可以,我一直说的是成本是不是合得上,正常开发一套东西用系统的同步方式处理简单出错又少,对开发人员要求也低,如果用你这一套的话就复杂很多,对开发人员要求也高。

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

    但作为技术人员,对更复杂的技术的研究肯定是不可少的,所以我说作为技术储备没有任何问题,万一以后负载上来了总要有一个解决方案。
        21
    xuxu555   71 天前
        22
    yulon   69 天前
    楼上们真的信手拈来,不看源码在那空想:
    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 异步读写文件不用另一套东西?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1619 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 16:42 · PVG 00:42 · LAX 08:42 · JFK 11:42
    ♥ Do have faith in what you're doing.