V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
lesismal
V2EX  ›  程序员

看隔壁帖子,同类开源项目交流沟通的问题,继续撕一下

  •  
  •   lesismal ·
    lesismal · 12 小时 50 分钟前 · 353 次点击

    上个帖子 https://www.v2ex.com/t/1164795 没人回复,可能我在 v 站日常维护 golang 的形象和态度在各位坛友心里就像厕所的石头,所以没人想来评论免得被我喷吧。但是我个人比绝大多数人更加痛恨那些胡乱吹捧、造假欺骗的 golang 开源项目。

    详情:

    先声明一下,nbio 我自己已经放弃,原因在上面的 TechEmpower 的 issue 里已经说过。 所以我不需要 star ,就单纯看这些造假、欺骗用户的不爽,所以各位也别给我 star ,也别说我蹭热度。 而且放弃 nbio 后,我更新了 README 做了建议和原因说明,并且推荐了其他几个比较好的相关仓库,推荐的这几个仓库都是我做过研究比较熟悉、与其他同类项目做过对比才良心推荐的:

    golang websocket:

    golang epoll:

    跑人家仓库开 issue 去撕,有朋友说没必要,都是混口饭吃。 但就像罗永浩说的、不是每只鸟来到这个世上都是为了躲枪子的。看他怼西门子怼王自如怼西贝都很爽很支持。 我几年前就已经离开代码岗位了,也不需要靠这个找工作挣钱,所以也无所谓什么技术名声和职业生涯的影响,说说真话讲讲事实,心里舒坦。

    另外,隔壁 /t/1166845?p=1#reply76 里我也说了: 很多开源作者是没有开源精神的,他们是为了自己利益,一旦看到比自己好的、当然要加固自己的护城河。 如果是我,非常喜欢别人在我项目下面聊他们的同类项目、互相交流。

    总是有些人去做这些事情的,总是有些人会成为孤独的,所以生死看淡,该干就干。

    直面自己的不足、承认自己的错误,是人最大的勇敢之一, 真要好好搞开源,坦荡荡一些,有什么不好!

    sthwrong
        1
    sthwrong  
       12 小时 44 分钟前   ❤️ 1
    啊?跟踪了你的仓库,看 issue 邮件看得不亦乐乎,突然就没了?
    lesismal
        2
    lesismal  
    OP
       12 小时 26 分钟前
    @sthwrong
    突然就没了是指 nbio 删掉了?我说放弃不是这个意思,而是放弃进一步开发或者优化了,以后只做基础的维护。

    我总结了一些 nbio 可以优化的点,需要新开个仓库或者 v2 的方式,不与旧版本兼容:
    1. 不兼容标准库 http 了,改成纯异步,因为标准库是同步的方式、http handler 退出就意味着这个请求结束,但如果涉及 handler 内逻辑需要阻塞(例例如请求数据中间件、调用 rpc 、请求三房 api ),那么协程就需要常驻等待。
    2. 纯异步后,不用等到 http body 收完整就调用 handler ,并且提供异步的 OnBody 给用户使用。现在的方式是读到完整请求(包括大 body )再调用 http handler ,遇到比如上传大文件这种场景内存就扛不住了,所以应该改成异步、读到一点就处理一点、避免内存压力。
    3. buffer 的严格一对一分配和释放,这样有利于引入 c 的内存池 lib 例如 jemalloc 、tcmalloc 做内存优化。现在的方式,因为早期没考虑这么细,实现上使用 sync.Pool ,而 sync.Pool 即使不严格一对一 Put 也会在不需要的时候被 gc 、不会导致内存泄漏,所以当前版本不是严格的一对一分配释放,这样的话就没法使用 c 的内存池库优化了、因为会内存泄漏。我倒是想过另一个办法,利用 Finalizer 在变量被 gc 的时候自动去调用释放、避免有遗漏释放的情况,但这种毕竟也是不严格、如果遇到短期洪峰也可能会爆、还不如 runtime gc 压制 OOM 的效果好。
    4. protocol stack 的方式去实现协议栈的解析。比如 tcp/udp 收到数据后,给上层的 tls parser 去解析,tls 解析后得到的 buffer 再给 http 或者 websocket 的 parser 去解析。当前不是这种类似中间件、协议栈链的方式去层层传递的,所以支持多层次的协议或者一些扩展时实现起来比较痛苦。例如有些用户想用同一个端口监听 http 、sock5 、普通 tcp 自定义协议,nbio 现在的方式是硬编码、很难去做这种根据第一段 buffer 的内容判断是哪种协议再分流的功能,只能让用户自己实现 listener 然后再额外包装再转给 nbio 之类的,但这种观念方式意味着用户自己实现的 listener 需要为每个链接阻塞读到至少 N 字节的协议头数据、这意味着每个链接要开一个协程,与 nbio 的设计就冲突了。

    放弃的原因主要因为:
    1. 如果改纯异步,与现在兼容标准库 http 就设计冲突了。
    2. 上面提到的几个优化点,虽然实现方式了然于胸,但工作量不小,我现在没这个精力去做。
    3. golang 的性能虽然已经不错了,但我对它的性能还是不满意、甚至失望。尤其这种海量连接数的场景毕竟是少数、而且都是基础设施比如网关之类的,这种场景 c/c++/rust 性能和开销更优势,golang 除了开发效率、毫无优势,而能有这种并发量级的通常是大厂、有人力物力去用 c/c++/rust 做,比如 CF 开源的那个 rust 版的 pingora 。
    sthwrong
        3
    sthwrong  
       11 小时 50 分钟前   ❤️ 1
    了解,我当前只用 ws 。
    Nanosk
        4
    Nanosk  
       11 小时 29 分钟前
    go 协程池有推荐吗
    lesismal
        5
    lesismal  
    OP
       10 小时 43 分钟前
    @Nanosk
    go 协程池的几种主要实现方式:
    1. 早期最简单的 chan 方式,多数实现会支持常驻协程,性能一般,但是简单易用。
    2. gent 作者的 ants ,用 cond_t 实现,好像也是支持常驻协程。实现复杂,号称性能吊打其他协程池,但我和一些朋友实测并没有发现性能优势,而且实现的过于复杂,可能只是跟其他那些用 chan 的实现方式对比有优势。
    3. 字节家的 gopool ,链表作为任务队列,如果当前执行任务的协程数量小于协程池 size ,则直接创建新的协程去执行任务,否则就等待当前正在执行任务的协程 for 循环挨个取任务执行。这种相较于 1 、2 性能是最好的,实现也简单。但有个缺点,生产持续大于消费速度时,队列一直增长,没有对上游自动反馈和限流的机制。
    4. nbio/taskpool 的实现方式,与 3 中的字节家 gopool 类似、区别在于用 chan 做队列。


    1 、2 两种都是支持常驻协程。但是,大概 golang 1.18 以后,runtime 自己有 goroutine 复用之类的,所以 go func()开销很小,比 1 、2 用 chan 、cond_t 那些实现方式性能更好,而且省掉了常驻协程。常见的 rpc 框架中、每个 Call 的处理默认都是 go func(),压测每秒几十万次 go func()都没什么压力,因为任务快速、同时并发存在的协程数量不多。协程池本身就限制了协程池 size ,所以每次 go func()就可以了,根本没必要使用常驻协程等待任务到来、新任务用 chan 传递反倒浪费性能甚至大于 go func()的开销。


    3 、4 两种,多数时候设置的协程池 size 是 1w 以上,多数的业务,整个系统请求下有资源可能阻塞才会让协程池的协程短暂驻留,但通常 1w 这种级别也足够用了,否则下有资源也扛不住太高的并发量级,而且下有通常也是自带池限制的、比如 http.Client 和 sql.DB 的连接池。
    而且多数情况是协程池 size 跑不满的,所以 3 、4 两种通常都是简单的原子判断协程池 size 、然后 go func()去执行、性能最好也最简单。


    所以 1 、2 的那些库我是不推荐的。


    我自己在 nbio 中使用自己的这种实现,因为 nbio 的主要设计目标就是资源控制、避免严重的 STW 和 OOM ,所以这种上下游之间的自动反馈和限流很有用。
    如果你的业务上游自己有对协程池的限流,则直接使用字节家的就好,否则建议用 nbio 的这种。


    字节家的:
    https://github.com/bytedance/gopkg/tree/main/util/gopool

    nbio 的(实现的很简单,百十来行有效代码,如果需要定制之类的、自己拷贝过去随便修改即可,feel free ):
    https://github.com/lesismal/nbio/blob/master/taskpool/taskpool.go
    Nanosk
        6
    Nanosk  
       10 小时 22 分钟前   ❤️ 1
    @lesismal 感谢大佬
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   939 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:55 · PVG 04:55 · LAX 13:55 · JFK 16:55
    ♥ Do have faith in what you're doing.