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

标签 go timeout http-status-codes

我有一些用 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","Status":200,"Body":"..."}, 
        {"Id":"baz","Status":404,"Body":"..."}, 
        ...
    ]
}

有一个本地服务器正在运行,它的运行速度故意很慢(休眠 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 状态代码,显然我想在我发送的聚合响应中反射(reflect)出来返回)。

完整代码如下。任何帮助表示赞赏。

    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

关于go - golang中如何处理HTTP超时错误和访问状态码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32038440/

相关文章:

javascript - 如何让 NodeJs 函数等待?

java - 在 Play 中返回 HTTP 状态 "created"!框架

python - Golang - 检测 JSON 输入中的重复键

go - 如何在 if-else 中初始化错误类型

tcp - Google Go EOF 使用 Read() 从连接读取

go - channel 数组

data-structures - 允许高效优先级更新的优先级队列?

java - 不在 digital ocean 服务器中发送电子邮件

ajax - AJAX问题: server is not returning proper status code in the event of a error

rest - HTTP 响应 header 的约定,用于通知客户端已弃用的 API