用go寫爬蟲服務並發請求,限制並發數


java寫爬蟲服務,思路是線程池,任務隊列,限制並行線程數即可。

 

go要用另一種設計思路,不能在線程層面限制,協程的異步請求,如果不作處理,並行發出所有網絡請求,因網絡請求數過多,會拋出異常

 

低版本的go可以並行執行map的操作,高版本會報異常,需要把map改為array,改起來很簡單

func updateAllShowTimePeople() {
    //得到要請求的url,多批次請求
    allurls := getShowTimeTypeIndexFromDB()
    //要請求的任務總數
    allurlscount := len(allurls)
    //每批次並行請求的數量(這里就是指同時request的數量,根據網絡和機型設置)
    gourp_url_count := 20
    //計算出一共需要執行幾組,注意邊界處理,例 21個url 每組5條,則要分5組(最后一組只有1條)
    group_count := allurlscount / gourp_url_count 
    //余數
    remainder := allurlscount % gourp_url_count
    if remainder != 0 {
    //有余數則多算一組
            group_count++ //6
    } else if group_count == 1 {
    //正好一組
            remainder = gourp_url_count
    }
    //組內 任務channel array
    chs := make([]chan bool, gourp_url_count)
    //遍歷每組 這里是串行的
    for i := 0; i < group_count; i++ {
        //用來保存每批次的結果
        pimap := make(map[int]int)
        //遍歷該批次內的任務,請求url
        for j := 0; j < gourp_url_count; j++ {
            chs[j] = make(chan bool)
            //不是最后一組則請求組內所有url || 是最后一組,序號小於余數的請求該url,序號大於余數的,無實際意義,直接 ch <- true。
            if (i != (group_count - 1)) || j < remainder {
                go getSingleShowTimeCurrentPeople(pimap, allurls[gourp_url_count * i + j], chs[j])
            } else {
                go function(){
                   ch <- true
                }
            }
        }
        //阻塞在這里,直到該批次內所有url都請求完畢。
        for _, ch := range chs {
            <-ch
        }
        //pimap 內保存改批次內所有url的請求結果,可以作進一步的處理,例,解析並存入數據庫。
        //在高級的go版本里會報並發錯誤,可以改用數組保存結果 getSingleShowTimeCurrentPeople(pimap, allurls[gourp_url_count * i + j], chs[j]) 中j 可用作數組索引
        UpdateShowTimeSaledByShowIndex(pimap)
    }
    fmt.Println("all show time  update finished")
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM