Go 的并发模型的一些问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bushenx
V2EX    问与答

Go 的并发模型的一些问题

  •  
  •   bushenx 2021-02-12 21:58:57 +08:00 2305 次点击
    这是一个创建于 1703 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在优化业务上的一块功能,现阶段这个功能会对用户的每个请求新建一个协程处理,但是个人感觉这样无节制的使用协程有些不妥。想在这上面优化一下,比如限制用户新建协程的数量。有这个想法但是具体实现应该如何做?有什么书籍或者文章介绍类似这样协程并发模型的,可以推荐学习一下吗?
    19 条回复    2021-02-19 14:05:40 +08:00
    pythonnoob
        1
    pythonnoob  
       2021-02-12 22:17:50 +08:00 via iPhone   1
    直接用消息队列削谷平峰,或者用令牌桶限制数量
    bushenx
        2
    bushenx  
    OP
       2021-02-12 22:23:35 +08:00 via Android
    @pythonnoob 令牌桶有使用,但是想在协程创建的地方也控制一下协程的并发数量,可以给支个招或者有什么别的渠道学习一下吗?
    matrix67
        3
    matrix67  
       2021-02-12 22:24:38 +08:00   1
    用户的每个请求当一个任务,丢到队列里面去,然后 go 开 worker 去解决任务。
    bushenx
        4
    bushenx  
    OP
       2021-02-12 22:26:29 +08:00 via Android
    @matrix67 当时是想到这个方法,但是如果用户接入量很多,队列是不是需要一个全局锁去保护,这样感觉有失性能。
    bushenx
        5
    bushenx  
    OP
       2021-02-12 22:28:19 +08:00 via Android
    我想能不能有什么并发模型能限制每个用户起协程的数量,但是又不会因为同步而损失太多性能。
    rrfeng
        6
    rrfeng  
       2021-02-13 00:01:54 +08:00 via Android
    千万级 goroutine 没什么问题。
    延时敏感的也不会用 go 吧。
    namaketa
        7
    namaketa  
       2021-02-13 00:55:23 +08:00 via Android
    一切性能问题都要问问自己为什么不能提配置 /加机器解决呢。
    协程调度开销已经很低了,特别对于重 io 任务。
    建议跑跑 benchmark 自己看调度耗时占比,再去判断要不要优化。
    golang 管道性能确实比较一般,可以多开几个管道。
    如果你真的有千万级别 /低时延 /重计算的任务,放过 go 吧。
    faker1
        8
    faker1  
       2021-02-13 01:56:59 +08:00   1
    1 楼的感觉可以, 实在想做感觉 可以参考 go 自己的任务调度, 锁的粒度放细, (全局,局部)类似分 group , 感觉这个是过度搞的,好像
    ginjedoad
        9
    ginjedoad  
       2021-02-13 08:15:41 +08:00
    使用协程池就好了。
    ginjedoad
        10
    ginjedoad  
       2021-02-13 08:19:27 +08:00   1
    比如这位同学写的稍微复杂了点。但是对于协程的限制数量级限制的同时,整体性能不升反降。https://github.com/panjf2000/ants

    “单机上百万上千万的同步批量任务处理现实意义不大,但是在异步批量任务处理方面有很大的应用价值,所以我个人觉得,Goroutine Pool 真正的价值还是在:

    限制并发的 goroutine 数量;
    复用 goroutine,减轻 runtime 调度压力,提升程序性能;
    规避过多的 goroutine 侵占系统资源( CPU&内存)。”
    sujin190
        11
    sujin190  
       2021-02-13 09:57:25 +08:00 via Android   1
    在线程外设计协程本来就是为了干这个的啊,每个请求一个协程,你们倒好,居然还怕协程创建太多,真是服了
    sujin190
        12
    sujin190  
       2021-02-13 10:04:02 +08:00 via Android
    之前做锁服务的时候测试过,每个请求一个协程,十万级 rps 并没有啥问题,想要更高确实需要协程复用,但这个过程必须是无锁的,无锁协程池并不是每个场景都能有的,web 这种真没啥必要
    bushenx
        13
    bushenx  
    OP
       2021-02-13 11:07:10 +08:00 via Android
    或许是我的表述不够明确,业务背景是服务会处理所有用户的请求,假设某个用户在某时间段请求数量剧增,这就导致会创建很多协程,而很多的协程会影响其他用户创建的协程。我是想减轻单个用户对所有用户的影响,所以限制协程数量。
    scnace
        14
    scnace  
       2021-02-14 20:54:20 +08:00 via Android
    你自己做个 benchmark 就知道了啊, 反正楼上的人说了你也不敢直接就这么干吧。。实在不行就上 goroutine pool 呗。。
    zxCoder
        15
    zxCoder  
       2021-02-15 00:48:12 +08:00
    歪个楼问一句,要看懂楼上大佬们所讨论的东西,大概要几年的工作 /golang 经验
    pythonnoob
        16
    pythonnoob  
       2021-02-19 11:39:27 +08:00 via iPhone
    @bushenx 加机器。除非到了加机器也解决不了的情况否则别做这种优化。
    pythonnoob
        17
    pythonnoob  
       2021-02-19 11:42:35 +08:00 via iPhone
    协程的调度器是无数大牛做出来的,一般人做所谓的优化很多时候会适得其反。请求激增的情况应该首先考虑加机器、前端或反代限流这些极其轻松的手段。
    pythonnoob
        18
    pythonnoob  
       2021-02-19 11:44:12 +08:00 via iPhone
    除非是 bat 、12306 这种体量,否则通过优化架构已经可以解决 99%的问题了
    bushenx
        19
    bushenx  
    OP
       2021-02-19 14:05:40 +08:00 via Android
    @pythonnoob 我的问题楼上的老哥已经给出答案了,就是实现一个协程池。因为我的逻辑是根据用户的请求创建协程,这很可能会导致协程被无休止创建。但是协程池就可以很好解决这个问题。在同步任务下协程池确实是没有必要的,go 运行时会有逻辑复用 g,但是这异步任务下协程池就可以很好的控制协程数量。我这个需求应该不算是性能优化,是极端情况下的一种保护措施。
    关于     帮助文档     自助推广系统     博客     API   FAQ     Solana     1577 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 16:15 PVG 00:15 LAX 09:15 JFK 12:15
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86