From 9f39e618edc107ce663c927669eb74373b6cfa6a Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 6 May 2020 15:00:02 +0300 Subject: [PATCH] lib/promscrape/discovery/gce: discover per-zone instances for `gce_sd_config` in parallel. This should reduce discovery latency --- lib/promscrape/discovery/gce/gce.go | 5 +-- lib/promscrape/discovery/gce/instance.go | 46 ++++++++++++++++-------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/lib/promscrape/discovery/gce/gce.go b/lib/promscrape/discovery/gce/gce.go index 9fe537c25..52044edff 100644 --- a/lib/promscrape/discovery/gce/gce.go +++ b/lib/promscrape/discovery/gce/gce.go @@ -53,9 +53,6 @@ func GetLabels(sdc *SDConfig) ([]map[string]string, error) { if err != nil { return nil, fmt.Errorf("cannot get API config: %s", err) } - ms, err := getInstancesLabels(cfg) - if err != nil { - return nil, fmt.Errorf("error when fetching instances data from GCE: %s", err) - } + ms := getInstancesLabels(cfg) return ms, nil } diff --git a/lib/promscrape/discovery/gce/instance.go b/lib/promscrape/discovery/gce/instance.go index 89281aeff..b75e17002 100644 --- a/lib/promscrape/discovery/gce/instance.go +++ b/lib/promscrape/discovery/gce/instance.go @@ -6,32 +6,48 @@ import ( "net/http" "strings" + "github.com/VictoriaMetrics/VictoriaMetrics/lib/logger" "github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils" ) // getInstancesLabels returns labels for gce instances obtained from the given cfg -func getInstancesLabels(cfg *apiConfig) ([]map[string]string, error) { - insts, err := getInstances(cfg) - if err != nil { - return nil, err - } +func getInstancesLabels(cfg *apiConfig) []map[string]string { + insts := getInstances(cfg) var ms []map[string]string for _, inst := range insts { ms = inst.appendTargetLabels(ms, cfg.project, cfg.tagSeparator, cfg.port) } - return ms, nil + return ms } -func getInstances(cfg *apiConfig) ([]Instance, error) { - var insts []Instance - for _, zone := range cfg.zones { - zoneInsts, err := getInstancesForProjectAndZone(cfg.client, cfg.project, zone, cfg.filter) - if err != nil { - return nil, err - } - insts = append(insts, zoneInsts...) +func getInstances(cfg *apiConfig) []Instance { + // Collect instances for each zone in parallel + type result struct { + zone string + insts []Instance + err error } - return insts, nil + ch := make(chan result, len(cfg.zones)) + for _, zone := range cfg.zones { + go func(zone string) { + insts, err := getInstancesForProjectAndZone(cfg.client, cfg.project, zone, cfg.filter) + ch <- result{ + zone: zone, + insts: insts, + err: err, + } + }(zone) + } + var insts []Instance + for range cfg.zones { + r := <-ch + if r.err != nil { + logger.Errorf("cannot collect instances from zone %q: %s", r.zone, r.err) + continue + } + insts = append(insts, r.insts...) + } + return insts } func getInstancesForProjectAndZone(client *http.Client, project, zone, filter string) ([]Instance, error) {