最近有个朋友, 刚入职没多久就被组长叼了, 原因是他在业务场景中开Goroutine导致测试服务器资源占用过大, 其他服务都崩了…
场景类似于监听区块链交易, 对每个区块进行轮询处理每笔交易, 他直接循环开Goroutine处理每笔交易, 数据大了goroutine开的太多导致资源占用过大, 导致了这场悲剧;
工作中我们需要开Goroutine来提高代码处理的效率, 但也不能滥用, 需要对它进行一定限制, 保证资源占用在可控范围内, 所以我们需要对项目中Goroutine的数量进行限制, 用channel就可以很好的做到;
正文直接上代码
gopool
package gopool
import "sync"
type Pool struct {
wg sync.WaitGroup
queue chan struct{}
}
// NewGoPool 实例化一个go程池
func NewGoPool(i int) *Pool {
if i < 1 {
i = 1
}
return &Pool{queue: make(chan struct{}, i)}
}
// Add 添加
func (p *Pool) Add() {
p.queue <- struct{}{}
p.wg.Add(1)
}
// Done 释放
func (p *Pool) Done() {
p.wg.Done()
<-p.queue
}
// Wait 等待
func (p *Pool) Wait() {
p.wg.Wait()
}
test
package gopool
import (
"fmt"
"runtime"
"testing"
"time"
)
func TestNewGoPool(t *testing.T) {
defaultNum := runtime.NumGoroutine()
p := NewGoPool(2)
for i := 0; i < 100; i++ {
p.Add()
go func() {
defer p.Done()
time.Sleep(1 * time.Second)
fmt.Println("go routine num: ", runtime.NumGoroutine()-defaultNum)
}()
}
p.Wait()
fmt.Println("go routine num: ", runtime.NumGoroutine())
}
代码都在我的个人项目 fly 中, 里面封装了一些常用的组件和应用示例, 欢迎大家 star
/ 提 Issues
;
项目瓶颈期了…
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)