我正在對不同的 URL 進行并發 GET 請求(在本例中為 1000)。對于這些要求,我遵循了消費者-生產者設計。有 50 個工人(goroutines - 爬蟲)和 1 個生產者(用 url 填充頻道)。問題:我已將客戶端中的超時設置為 15 秒(我不想等待每個請求超過 15 秒)。但是當一個 URL 使 goroutine 等待超過 15 秒時,我的代碼退出超出上下文期限(Client.Timeout 或閱讀正文時取消上下文)想要的行為:當服務器花費超過 15 秒時,我希望相關的 goroutine 簡單地繼續下一個 URL這是代碼片段:package mainimport ( "bufio" "fmt" "io" "log" "net/http" "os" "sync" "time")func crawler(wg *sync.WaitGroup, urlChannel <-chan string) { defer wg.Done() client := &http.Client{Timeout: 15 * time.Second} // single client is sufficient for multiple requests for urlItem := range urlChannel { req1, _ := http.NewRequest("GET", "http://"+urlItem, nil) // generating the request req1.Header.Add("User-agent", "Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/74.0") // changing user-agent resp1, respErr1 := client.Do(req1) // sending the prepared request and getting the response if respErr1 != nil { fmt.Println("server error", urlItem) continue } if resp1.StatusCode/100 == 2 { // means server responded with 2xx code f1, fileErr1 := os.Create("200/" + urlItem + "_original.txt") // creating the relative file if fileErr1 != nil { fmt.Println("file error", urlItem) log.Fatal(fileErr1) } _, writeErr1 := io.Copy(f1, resp1.Body) // writing the sourcecode into our file if writeErr1 != nil { fmt.Println("file error", urlItem) log.Fatal(writeErr1) } f1.Close() resp1.Body.Close() fmt.Println("success:", urlItem) } }}如何實現想要的行為(如果達到超時,則跳過 URL)?
1 回答

智慧大石
TA貢獻1946條經驗 獲得超3個贊
大概就在這里:
_, writeErr1 := io.Copy(f1, resp1.Body) // writing the sourcecode into our file if writeErr1 != nil { fmt.Println("file error", urlItem) log.Fatal(writeErr1) }
這個操作的結果不一定是寫錯誤,可能是讀錯誤,在這種情況下,很可能是。響應正文的讀取超時。
不要打電話log.Fatal
給這種情況。
- 1 回答
- 0 關注
- 185 瀏覽
添加回答
舉報
0/150
提交
取消