如何在golang中处理HTTP超时错误和访问状态代码

我有一些用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非常有权威 – 他解释得比我更好.

https://www.youtube.com/watch?v=f6kdp27TYZs

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...