Go语言圣经习题练习_1.6并发获取多个URL
练习 1.10: 找一个数据量比较大的网站,用本小节中的程序调研网站的缓存策略,对每个URL执行两遍请求,查看两次时间是否有较大的差别,并且每次获取到的响应内容是否一致,修改本节中的程序,将响应结果输出,以便于进行对比。
练习 1.11: 在fatchall中尝试使用长一些的参数列表,比如使用在alexa.com的上百万网站里排名靠前的。如果一个网站没有回应,程序将采取怎样的行为?(Section8.9 描述了在这种情况下的应对机制)。
package main import ( "fmt" "io/ioutil" "net/http" "os" "time" "strings" "io" "sort" ) func fetchUrl(url string, ch chan <- map[string]string) { //使用map记录,url -> response start := time.Now() resp,err := http.Get(url) result := make(map[string]string) if err != nil { result[url] = fmt.Sprintf("http-get: %v",err) ch <- result return } nbytes,err := io.Copy(ioutil.Discard,resp.Body) if err != nil { result[url] = fmt.Sprintf("while reading:%v %v",url,err) ch <- result return } resp.Body.Close() secs := time.Since(start).Seconds() //fmt.Printf("%v %v %v Bytes %v's\n",url,resp.Status,nbytes,secs) result[url] = fmt.Sprintf("%v %v %v Bytes %v's",url,resp.Status,nbytes,secs) ch <- result } func main() { start := time.Now() ch := make(chan map[string]string) count := 0 for _,url := range os.Args[1:] { if ! strings.HasPrefix(url,"htto") { url = "http://" + url } fmt.Printf("start fetch %v\n",url) go fetchUrl(url,ch) // 重复3次 go fetchUrl(url,ch) go fetchUrl(url,ch) count += 3 } result := make(map[string]string) keys := []string{} for i:=0;i<count;i++{ for k,v := range <-ch { result[k] = v keys = append(keys,k) } } sort.Strings(keys) //按照url排序 for _,k := range keys { fmt.Printf("%s : %s\n",k,result[k]) //输出按照URL排序后的结果 } fmt.Printf("done, use %v seconds",time.Since(start).Seconds()) }
运行测试
go run main.go baidu.com sina.cn 163.com google.cn qq.com weibo.cn start fetch http://baidu.com start fetch http://sina.cn start fetch http://163.com start fetch http://google.cn start fetch http://qq.com start fetch http://weibo.cn http://163.com : http://163.com 200 OK 648796 Bytes 0.8530488's http://163.com : http://163.com 200 OK 648796 Bytes 0.8530488's http://163.com : http://163.com 200 OK 648796 Bytes 0.8530488's http://baidu.com : http://baidu.com 200 OK 81 Bytes 0.0630036's http://baidu.com : http://baidu.com 200 OK 81 Bytes 0.0630036's http://baidu.com : http://baidu.com 200 OK 81 Bytes 0.0630036's http://google.cn : http://google.cn 200 OK 3213 Bytes 0.3580205's http://google.cn : http://google.cn 200 OK 3213 Bytes 0.3580205's http://google.cn : http://google.cn 200 OK 3213 Bytes 0.3580205's http://qq.com : http://qq.com 200 OK 248761 Bytes 0.3360192's http://qq.com : http://qq.com 200 OK 248761 Bytes 0.3360192's http://qq.com : http://qq.com 200 OK 248761 Bytes 0.3360192's http://sina.cn : http://sina.cn 200 OK 14147 Bytes 0.1520087's http://sina.cn : http://sina.cn 200 OK 14147 Bytes 0.1520087's http://sina.cn : http://sina.cn 200 OK 14147 Bytes 0.1520087's http://weibo.cn : http://weibo.cn 200 OK 5293 Bytes 0.3700212's http://weibo.cn : http://weibo.cn 200 OK 5293 Bytes 0.3700212's http://weibo.cn : http://weibo.cn 200 OK 5293 Bytes 0.3700212's done, use 0.8830505 seconds