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
Go语言圣经习题练习_1.6并发获取多个URL的更多相关文章
- Go语言圣经习题练习_1.7. Web服务
练习 1.12: 修改Lissajour服务,从URL读取变量,比如你可以访问 http://localhost:8000/?cycles=20 这个URL,这样访问可以将程序里的cycles默认的5 ...
- Go语言圣经习题练习_1.4. GIF动画
练习 1.5: 修改前面的Lissajous程序里的调色板,由黑色改为绿色.我们可以用color.RGBA{0xRR, 0xGG, 0xBB, 0xff}来得到#RRGGBB这个色值,三个十六进制的字 ...
- Go语言圣经习题练习_1.5. 获取URL
练习 1.7: 函数调用io.Copy(dst, src)会从src中读取内容,并将读到的结果写入到dst中,使用这个函数替代掉例子中的ioutil.ReadAll来拷贝响应结构体到os.Stdout ...
- [日常] GO语言圣经-并发获取多个URL
go语言圣经-并发获取多个URL 1.GO最新奇的特性就是对并发编程的支持,goroutine和channel 2.goroutine是一种函数的并发执行方式,而channel是用来在goroutin ...
- golang学习 ---并发获取多个URL
package main import ( "fmt" "io" "io/ioutil" "net/http" &quo ...
- [日常] Go语言圣经-WEB服务与习题
Go语言圣经-web服务 1.Web服务程序,标准库里的方法已经帮我们完成了大量工作 2.main函数将所有发送到/路径下的请求和handler函数关联起来,/开头的请求其实就是所有发送到当前站点上的 ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- [日常] Go语言圣经-Panic异常,Recover捕获异常习题
Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的pan ...
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
随机推荐
- 面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)
一.概述 面向过程:根据业务逻辑从上到下写代码 函数式:将具有一些功能的代码封装到函数中,需要的时候调用即可 面向对象:对函数进行分类和封装,让开发更方便,更快捷 Java和C#只支持面型对象编程,, ...
- cloudsim 3.0.3下载与安装教程
1.配置jdk(之前的文章都讲解过,这里就不具体说了) 2.安装eclipse或MyEclipse 3.下载cloudsim压缩包,这个的官网是需要FQ,这里贴上我的下载地址 链接:https://p ...
- java中Array和ArrayList区别
1)精辟阐述:可以将 ArrayList想象成一种“会自动扩增容量的Array”. 2)Array([]):最高效:但是其容量固定且无法动态改变: ArrayList: 容量可动态增长:但牺 ...
- 每日一问:到底为什么属性动画后 View 在新位置还能响应事件
在 Android 开发中,我们难免会使用动画来处理各种各样的动画效果,以满足 UI 的高逼格设计.对于比较复杂的动画效果,我们通常会采用著名的开源库:lottie-android,或许你会对 lot ...
- php.ini Xdebug配置
在此记录: xdebug.profiler_output_dir="H:\install\phpStudy\tmp\xdebug"xdebug.trace_output_dir=& ...
- Storm 学习之路(七)—— Storm集成 Redis 详解
一.简介 Storm-Redis提供了Storm与Redis的集成支持,你只需要引入对应的依赖即可使用: <dependency> <groupId>org.apache.st ...
- Redis Ubuntu 安装
1.使用 root 用户登录 Ubuntu 2. wget http://download.redis.io/releases/redis-5.0.3.tar.gz 下载最新的稳定版本到 redis ...
- java中session和application的用法
Session的用法 首先创建2个jsp文件t1.jsp t2.jsp 在t1.jsp <% //设置session的键与值 session.setAttribute("abc&qu ...
- django基础知识之QueryDict对象:
QueryDict对象 定义在django.http.QueryDict request对象的属性GET.POST都是QueryDict类型的对象 与python字典不同,QueryDict类型的对象 ...
- python的简介与简单使用
简介: python的诞生 创始人:Guido van Rossum(荷兰人:吉多) 时间:1989年 特点: 1.简单明了,容易上手 2.多平台,`全面发展,平衡发展, 3.胶水语言,有大量的库 其 ...