1
pythonnoob 2021-02-12 22:17:50 +08:00 via iPhone 1
直接用消息队列削谷平峰,或者用令牌桶限制数量
|
2
bushenx OP @pythonnoob 令牌桶有使用,但是想在协程创建的地方也控制一下协程的并发数量,可以给支个招或者有什么别的渠道学习一下吗?
|
3
matrix67 2021-02-12 22:24:38 +08:00 1
用户的每个请求当一个任务,丢到队列里面去,然后 go 开 worker 去解决任务。
|
4
bushenx OP @matrix67 当时是想到这个方法,但是如果用户接入量很多,队列是不是需要一个全局锁去保护,这样感觉有失性能。
|
5
bushenx OP 我想能不能有什么并发模型能限制每个用户起协程的数量,但是又不会因为同步而损失太多性能。
|
6
rrfeng 2021-02-13 00:01:54 +08:00 via Android
千万级 goroutine 没什么问题。
延时敏感的也不会用 go 吧。 |
7
namaketa 2021-02-13 00:55:23 +08:00 via Android
一切性能问题都要问问自己为什么不能提配置 /加机器解决呢。
协程调度开销已经很低了,特别对于重 io 任务。 建议跑跑 benchmark 自己看调度耗时占比,再去判断要不要优化。 golang 管道性能确实比较一般,可以多开几个管道。 如果你真的有千万级别 /低时延 /重计算的任务,放过 go 吧。 |
8
faker1 2021-02-13 01:56:59 +08:00 1
1 楼的感觉可以, 实在想做感觉 可以参考 go 自己的任务调度, 锁的粒度放细, (全局,局部)类似分 group , 感觉这个是过度搞的,好像
|
9
ginjedoad 2021-02-13 08:15:41 +08:00
使用协程池就好了。
|
10
ginjedoad 2021-02-13 08:19:27 +08:00 1
比如这位同学写的稍微复杂了点。但是对于协程的限制数量级限制的同时,整体性能不升反降。https://github.com/panjf2000/ants
“单机上百万上千万的同步批量任务处理现实意义不大,但是在异步批量任务处理方面有很大的应用价值,所以我个人觉得,Goroutine Pool 真正的价值还是在: 限制并发的 goroutine 数量; 复用 goroutine,减轻 runtime 调度压力,提升程序性能; 规避过多的 goroutine 侵占系统资源( CPU&内存)。” |
11
sujin190 2021-02-13 09:57:25 +08:00 via Android 1
在线程外设计协程本来就是为了干这个的啊,每个请求一个协程,你们倒好,居然还怕协程创建太多,真是服了
|
12
sujin190 2021-02-13 10:04:02 +08:00 via Android
之前做锁服务的时候测试过,每个请求一个协程,十万级 rps 并没有啥问题,想要更高确实需要协程复用,但这个过程必须是无锁的,无锁协程池并不是每个场景都能有的,web 这种真没啥必要
|
13
bushenx OP 或许是我的表述不够明确,业务背景是服务会处理所有用户的请求,假设某个用户在某时间段请求数量剧增,这就导致会创建很多协程,而很多的协程会影响其他用户创建的协程。我是想减轻单个用户对所有用户的影响,所以限制协程数量。
|
14
scnace 2021-02-14 20:54:20 +08:00 via Android
你自己做个 benchmark 就知道了啊, 反正楼上的人说了你也不敢直接就这么干吧。。实在不行就上 goroutine pool 呗。。
|
15
zxCoder 2021-02-15 00:48:12 +08:00
歪个楼问一句,要看懂楼上大佬们所讨论的东西,大概要几年的工作 /golang 经验
|
16
pythonnoob 2021-02-19 11:39:27 +08:00 via iPhone
@bushenx 加机器。除非到了加机器也解决不了的情况否则别做这种优化。
|
17
pythonnoob 2021-02-19 11:42:35 +08:00 via iPhone
协程的调度器是无数大牛做出来的,一般人做所谓的优化很多时候会适得其反。请求激增的情况应该首先考虑加机器、前端或反代限流这些极其轻松的手段。
|
18
pythonnoob 2021-02-19 11:44:12 +08:00 via iPhone
除非是 bat 、12306 这种体量,否则通过优化架构已经可以解决 99%的问题了
|
19
bushenx OP @pythonnoob 我的问题楼上的老哥已经给出答案了,就是实现一个协程池。因为我的逻辑是根据用户的请求创建协程,这很可能会导致协程被无休止创建。但是协程池就可以很好解决这个问题。在同步任务下协程池确实是没有必要的,go 运行时会有逻辑复用 g,但是这异步任务下协程池就可以很好的控制协程数量。我这个需求应该不算是性能优化,是极端情况下的一种保护措施。
|