我需求是写一个exporter,输出一些监控指标。通过调用多个shell命令得到返回结果,再通过golang的http.HandleFunc来实现一个http服务。
现在我通过go metricsProducer(metricsChannel)实现了并发执行,并将输出写入到metricsChannel中,但是输出的时候却被阻塞了,http服务一直无返回,以下是源码:小弟刚学go,不太明白channel以及并发这块,还请大神们多指教。
```go
var metricsChannel = make(chan string, 10)
func exec_shell(s string) (string){
cmd := exec.Command("/bin/bash", "-c", s)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
return out.String()
}
func metricsConsumer(metricsChannel chan string, w http.ResponseWriter) {
for metrics := range metricsChannel {
fmt.Println(metrics)
io.WriteString(w, metrics)
}
defer close(metricsChannel)
}
func ExporterHandler(w http.ResponseWriter, r *http.Request){
metricsConsumer(metricsChannel, w)
}
func main(){
port := flag.String("port", "30083", "Input your exporter port")
flag.Parse()
runtime.GOMAXPROCS(runtime.NumCPU())
go metricsProducer(metricsChannel)
http.HandleFunc("/metrics", ExporterHandler)
url := fmt.Sprintf("%s:%s", "127.0.0.1", *port)
fmt.Println("url=", url+"/metrics")
err := http.ListenAndServe(url, nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
func metricsProducer(metricsChannel chan<- string) {
commands := [3]string{"ls", "ls -lrt", "hostname -i"}
for _, cmd := range commands {
metricsChannel <- fetchMetrics(cmd, "this is test")
}
}
func fetchMetrics(command, describe string) (string) {
metrics := fmt.Sprintf("%s", exec_shell(command))
return "#" + describe + "\n" + metrics
}
```
有疑问加站长微信联系(非本文作者)