[英]The best way to manage a dynamic goroutine pool
假設我有一個任務提供者 - 可讀渠道,它可能會也可能不會提供任務(取決於工作量)具體是因為幾個小時可能沒有工作然后可能會突然出現任務
我想讓我的goroutine池從1增長到N,其中N是工作出現時的最大並發數,然后自動折疊到1,其中goroutine的工作時間超過X秒以避免內存/ CPU浪費。
我本可以使用一個固定的游泳池,因為goroutines很便宜,但我不喜歡有數以千計的閑置goroutines我可能更好地使用這些資源(應該主要是ram但仍然)
折疊部分相當容易
for {
timeoutTimer := time.NewTimer(WORKER_ROUTINE_TIMEOUT)
select {
case taskContext, isBatchRunning := <-runner.tasksCh:
if !isBatchRunning {
log.Print("task provider is closed, quit worker goroutine")
return
}
runner.job.Process(&taskContext)
case <-timeoutTimer.C:
return
}
}
但我不確定如何使池動態增長,即在哪種情況下產生一個新的
此池的優先級是能夠在增加的負載下快速做出反應並擴展到N(最大並發)goroutine,當工作負載減少時能夠最終崩潰到更合理的數字(1分鍾)
PS我看到了一個https://github.com/Jeffail/tunny包,但看起來它沒有類似於當前池大小的自適應縮放。 我錯過了什么嗎?
謝謝!
好吧,我不確定你需要一個游泳池。 Goroutines很快就會推出,你可能不需要一直保持准備就緒。
對於這個任務,我會使用一個簡單的信號量。 使用通道在Go中實現信號量非常容易。 你可以在這里看到我的個人例子。
您只需創建一個具有所需容量的信號量(這將是您允許的最大goroutines數),然后:
就那么簡單。 並且不用擔心需要按需啟動它們; 它真的過度優化了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.