求大佬解惑

https://zhuanlan.zhihu.com/p/48028065 https://github.com/cahitbeyaz/job-worker 请教大家个问题。 上面是2种控制goroutine数量的方法,或者叫协程池。第一种挺简单,第二种挺麻烦,大家也知道fasthttp也写了一个复杂的协程池,为什么不直接使用第一个那种简单的方法呢?还是说我理解的有问题呢? 第一种很简单,创建一个有缓冲的channel,起一个goroutine就往channel写入一个数据,channel满了就阻塞等待,如果一个goroutine结束了,就从channel取一个数据丢弃,这样就控制了goroutine数量。 第二种呢,比较麻烦,感觉跟第一种相比,都是控制了goroutine 的数量,无非第一种是频繁创建并销毁goroutine,第二种是提前创建好goroutine循环利用,但是goroutine的开销是很小的,有必要用第二种方法吗?又提高了编码的复杂性。

已邀请:

heramerom

赞同来自:

第一种只是限制了并发数,并不能叫池吧。 协程很小,但是创建销毁也是有损耗的。在一些场景下,第二种写法也是有必要的。

wuhan

赞同来自:

看了第二种的代码,个人感觉可以让所有worker共用一个job queue,这样代码可以简化很多

meagle - 软件开发工程师

赞同来自:

第一种,https://zhuanlan.zhihu.com/p/48028065 介绍了如何“限制 http.Server 并发使用的 goroutine”。这里也有一个关于限制http.Server并发的讨论,如果限制http.Server使用的并发数,那也许不能发挥系统的性能。具体视情况而定吧。

第二种,https://github.com/cahitbeyaz/job-worker ,关于里面提起的文章大概是这样的吧。

  • 起因:因为,每来一个请求,就创建一个协程,用于上传数据到AWS。 结果:There is no way to control how many go routines we are spawning.。
  • 第一个解决方案:靠一个buffered channel来限制创建的协程数量,当请求远远大于buffer channel值时,势必为造成阻塞。结果:Our latency rates kept increasing in a constant rate minutes after we deployed this flawed version.
  • 第二个解决方案:1. 将要上传到AWS的数据,放到一个缓存队列,并立即返回给客户端200;2. 利用固定数量的协程,消费缓存队列中的数据,充分利用带宽。2-tier channel system, one for queuing jobs and another to control how many workers operate on the JobQueue concurrently.

关于这两种限制协程数量的方案,就https://zhuanlan.zhihu.com/p/48028065 而言,是否限制协程数量应该跟应用场景有关,另外,也可以使用sync.WaitGroup来实现限制协程数量。 就https://github.com/cahitbeyaz/job-worker 的应用场景而言,我认为使用缓存池的目的不是为了节省资源。

要回复问题请先登录注册