我有一些用Go编写的代码(见下文),它应该“扇出”HTTP请求,然后整理/聚合细节.
I’m new to golang and so expect me to be a nOOb and my knowledge to be limited
该程序的输出目前是这样的:
{ "Status":"success","Components":[ {"Id":"foo","Status":200,"Body":"..."},{"Id":"bar",{"Id":"baz","Status":404,... ] }
运行的本地服务器特意慢(睡眠5秒然后返回响应).但我列出了其他网站(见下面的代码),有时也会触发错误(如果它们出错,那就没关系).
我目前遇到的问题是如何最好地处理这些错误,特别是“超时”相关的错误;因为我不知道如何识别故障是超时还是其他错误?
目前我总是得到一揽子错误:
Get http://localhost:8080/pugs: read tcp 127.0.0.1:8080: use of closed network connection
http:// localhost:8080 / pugs通常是失败的URL(希望超时!).但正如你从代码中看到的那样(下图),我不确定如何确定错误代码与超时有关,也不确定如何访问响应的状态代码(我目前只是将其设置为404但是显然这是不对的 – 如果服务器出错了,我会期待类似500状态代码的东西,显然我想在我发回的聚合响应中反映出来.
完整的代码如下所示.任何帮助赞赏.
package main import ( "encoding/json" "fmt" "io/IoUtil" "net/http" "sync" "time" ) type Component struct { Id string `json:"id"` Url string `json:"url"` } type ComponentsList struct { Components []Component `json:"components"` } type ComponentResponse struct { Id string Status int Body string } type Result struct { Status string Components []ComponentResponse } var overallStatus string = "success" func main() { var cr []ComponentResponse var c ComponentsList b := []byte(`{"components":[{"id":"local","url":"http://localhost:8080/pugs"},{"id":"google","url":"http://google.com/"},{"id":"integralist","url":"http://integralist.co.uk/"},{"id":"sloooow","url":"http://stevesouders.com/cuzillion/?c0=hj1hfff30_5_f&t=1439194716962"}]}`) json.Unmarshal(b,&c) var wg sync.WaitGroup timeout := time.Duration(1 * time.Second) client := http.Client{ Timeout: timeout,} for i,v := range c.Components { wg.Add(1) go func(i int,v Component) { defer wg.Done() resp,err := client.Get(v.Url) if err != nil { fmt.Printf("Problem getting the response: %s\n",err) cr = append(cr,ComponentResponse{ v.Id,404,err.Error(),}) } else { defer resp.Body.Close() contents,err := IoUtil.ReadAll(resp.Body) if err != nil { fmt.Printf("Problem reading the body: %s\n",err) } cr = append(cr,ComponentResponse{ v.Id,resp.StatusCode,string(contents),}) } }(i,v) } wg.Wait() j,err := json.Marshal(Result{overallStatus,cr}) if err != nil { fmt.Printf("Problem converting to JSON: %s\n",err) return } fmt.Println(string(j)) }
如果你想散开然后聚合结果,并且你想要net / http包没有给你特定的超时行为,那么你可能想要使用goroutines和channel.
我今天刚观看了这个视频,它将使用Go的并发功能引导您完成这些场景.另外,扬声器Rob Pike非常有权威 – 他解释得比我更好.