Tôi có một số mã (xem bên dưới) được viết bằng Go, được yêu cầu "yêu cầu HTTP" của người hâm mộ và đối chiếu/tổng hợp lại chi tiết.Cách xử lý lỗi hết thời gian chờ HTTP và truy cập mã trạng thái trong golang
I'm new to golang and so expect me to be a nOOb and my knowledge to be limited
Đầu ra của chương trình hiện đang là một cái gì đó như:
{
"Status":"success",
"Components":[
{"Id":"foo","Status":200,"Body":"..."},
{"Id":"bar","Status":200,"Body":"..."},
{"Id":"baz","Status":404,"Body":"..."},
...
]
}
Có một máy chủ địa phương chạy đó là cố ý chậm (ngủ trong 5 giây và sau đó trả về một phản ứng). Nhưng tôi có các trang web khác được liệt kê (xem mã dưới đây) mà đôi khi kích hoạt một lỗi là tốt (nếu họ lỗi, thì đó là tốt).
Vấn đề tôi có vào lúc này là cách tốt nhất để xử lý các lỗi này và cụ thể là các lỗi liên quan đến "hết thời gian chờ"; trong đó tôi không chắc chắn làm thế nào để nhận ra nếu một thất bại là một thời gian chờ hoặc một số lỗi khác?
Tại thời điểm này tôi nhận được một lỗi chăn lại tất cả các thời gian: (! Hy vọng bởi thời gian chờ)
Get http://localhost:8080/pugs: read tcp 127.0.0.1:8080: use of closed network connection
đâu http://localhost:8080/pugs
nói chung sẽ là url rằng thất bại. Nhưng như bạn có thể thấy từ mã (bên dưới), tôi không chắc chắn cách xác định mã lỗi có liên quan đến thời gian chờ cũng như cách truy cập mã trạng thái của phản hồi (hiện tại tôi chỉ đặt chăn là 404
nhưng rõ ràng là không đúng - nếu máy chủ bị lỗi, tôi mong đợi một cái gì đó giống như mã trạng thái 500
và rõ ràng là tôi muốn phản ánh điều đó trong phản hồi tổng hợp mà tôi gửi lại).
Có thể xem mã đầy đủ bên dưới. Bất kỳ trợ giúp nào được đánh giá cao.
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))
}
Nhiều khả năng không liên quan đến vấn đề của bạn, nhưng bạn có một cuộc đua dữ liệu phụ thêm vào 'cr'. Bạn không thể viết cùng một biến từ nhiều goroutines mà không đồng bộ hóa. Bạn có thể muốn xây dựng/chạy với [máy dò cuộc đua] (https://blog.golang.org/race-detector). –
Cảm ơn nhận xét. Tôi sẽ xem xét để sử dụng các kênh thay vì + Tôi sẽ điều tra rằng máy dò cuộc đua :-) – Integralist
Nếu cuộc gọi của khách hàng trả về lỗi, không có mã trạng thái, vì không có yêu cầu http hoàn chỉnh. Không có nhiều bạn có thể làm với một lỗi tại thời điểm đó, nhưng trong go1.5 một client.Timeout sẽ ít nhất trả về một thông điệp tốt hơn trong một net.Error. – JimB