亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在并發 goroutine 中超時(截止日期)后“繼續”?

如何在并發 goroutine 中超時(截止日期)后“繼續”?

Go
喵喵時光機 2022-07-11 15:56:25
我正在對不同的 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給這種情況。


查看完整回答
反對 回復 2022-07-11
  • 1 回答
  • 0 關注
  • 185 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號