myzhan/boomer

该如何做到一个任务做完就释放呢?

ankisme opened this issue · 3 comments

func main() {
	task := &boomer.Task{
		Name:   "tcp",
		Weight: 10,
		Fn:     func() {
			1. 创建一个用户
			2. 这个用户做一系列时间,大约耗时5秒
			3. 任务结束
		},
	}

	boomer.Run(task)
}

参照上方的伪代码,我现在的需求是,一个task中创建一个用户,做一系列事情,差不多耗时5秒,然后这个用户的任务就完成了

但是,我看了/_examples/tcp/client.go这个例子,我发现这里面的work函数是for循环,会阻塞等待退出信号

所以,假如我创建10万个用户,如果参照/_examples/tcp/client.go这个例子来写,就有10万个协程持续不释放,直至压测完成,那我感觉这个压测结果就失真了,因为这些协程不释放白白耗掉了资源,而正常情况下每个协程执行5秒就释放了

分析func (r *runner) spawnWorkers代码后我发现boomer并不支持我的这类需求,除非我在task里自己写个for每隔一段时间去执行task,但这样我就用不到locust的那些时间间隔参数了

所以,感觉需要官方提供支持,或者是有什么办法能实现我这个需求呢?

另外,还有一点,我感觉boom的task模式真的很简陋,简陋到就像跟人在开玩笑一样,python的locust是可以做到一个用户根据权重执行不同task的,而目前boomer每个task则是分开的,比较难做到这点,而且目前官方示例里,提供的例子都是些什么foo、bar这种非常简陋的范例,这种范例太简单了没有可参考性,连参数都是预先写死的,一般压测都是模拟很多用户,而一个用户又不止做一件事情,而boomer的范例则看不到这类稍微复杂点的例子,我感觉,官方例子里起码要让人知道,怎么新建100个用户,然后这些用户按照一定的时间间隔和权重执行任务,这样才算现实世界中遇到的情况,而不是什么foo、bar那种简单的一次性函数执行完就没了。

func (r *runner) spawnWorkers(spawnCount int, quit chan bool, spawnCompleteFunc func()) {
	log.Println("Spawning", spawnCount, "clients at the rate", r.spawnRate, "clients/s...")

	for i := 1; i <= spawnCount; i++ {
		sleepTime := time.Duration(1000000/r.spawnRate) * time.Microsecond
		time.Sleep(sleepTime)

		select {
		case <-quit:
			// quit spawning goroutine
			return
		default:
			atomic.AddInt32(&r.numClients, 1)
			go func() {
				for {
					select {
					case <-quit:
						return
					default:
						if r.rateLimitEnabled {
							blocked := r.rateLimiter.Acquire()
							if !blocked {
								task := r.getTask()
								r.safeRun(task.Fn)
							}
						} else {
							task := r.getTask()
							r.safeRun(task.Fn)
						}
					}
				}
			}()
		}
	}

	if spawnCompleteFunc != nil {
		spawnCompleteFunc()
	}
}

如果只是为了一次性创建10万个用户,这个并不属于 boomer 的范畴,locust 也不支持这种需求,boomer 和 locust slave 一样,都是为了模拟有多少个用户持续性发请求的,然后得出压测过程中,rps, p99 这些指标,不是一次性请求就完事的

如果非要实现,在 task 里面干完事情主动调一下 runtime.Goexit 就行了。不过如 @boboalex 所说,这种压测场景不适合用 boomer。

好的,收到,感谢答复,我试试看