我知道有多种解决方案可以满足我的需求,但是我正在寻找一种/适当的方式来并行执行一些请求。我是Go的新手,但是我现在正在做的事情感觉很麻烦。
用例:
我需要并行查询4个不同的REST端点(kubernetes客户端请求)。一旦获得所有这4个结果,就需要进行一些处理。
我的问题:
我知道我需要为此使用go例程,但是收集结果的最佳方法是什么。我目前正在做的事情(请参见下面的代码示例)可能非常繁琐,但是我不确定我还能做些什么来改进代码。
代码:
此代码最容易理解,但我不想按顺序执行请求:
// Get node resource usage metrics
nodeMetricsList, err := c.kubernetesClient.NodeMetricses()
if err != nil {
log.Warn("Failed to get node usage list from Kubernetes", err)
return err
}
// Get pod resource usage metrics
podMetricsList, err := c.kubernetesClient.PodMetricses()
if err != nil {
log.Warn("Failed to get pod usage list from Kubernetes", err)
return err
}
这就是我并行运行请求的方式。这使得代码的可读性大大降低,实现起来也很麻烦:
var nodeMetricsList *v1beta1.NodeMetricsList
var nodeMetricsListError error
var podMetricsList *v1beta1.PodMetricsList
var podMetricsListError error
go func() {
nodeMetricsList, nodeMetricsListError = c.kubernetesClient.NodeMetricses()
}()
if nodeMetricsListError != nil {
log.Warn("Failed to get podList from Kubernetes", err)
return err
}
// Get pod resource usage metrics
go func() {
podMetricsList, podMetricsListError = c.kubernetesClient.PodMetricses()
}()
if podMetricsListError != nil {
log.Warn("Failed to get pod usage list from Kubernetes", err)
return err
}
在给定示例中并行执行请求的正确方法是什么?
答案 0 :(得分:4)
您的代码有2个竞争条件,可能永远不会正确报告错误。
您需要先等待goroutine完成,然后才能读取它们所操作的值,这可以通过sync.WaitGroup
轻松完成,如下所示:
var nodeMetricsList *v1beta1.NodeMetricsList
var podMetricsList *v1beta1.PodMetricsList
var nodeMetricsListError, podMetricsListError error
var wg sync.WaitGroup
// Get node resource usage metrics
wg.Add(1)
go func() {
defer wg.Done()
nodeMetricsList, nodeMetricsListError = c.kubernetesClient.NodeMetricses()
}()
// Get pod resource usage metrics
wg.Add(1)
go func() {
defer wg.Done()
podMetricsList, podMetricsListError = c.kubernetesClient.PodMetricses()
}()
wg.Wait()
if nodeMetricsListError != nil {
log.Warn("Failed to get podList from Kubernetes", err)
return err
}
if podMetricsListError != nil {
log.Warn("Failed to get pod usage list from Kubernetes", err)
return err
}
fmt.Println("Hello, playground")