我们公司产品是典型三层架构,前端是一个类似CDN的cache节点,后面挂着有N个proxy做高可用,proxy后面是真正的代码服务器,随着机器越来越多,偶尔会出现部分机器状态不一致而导致的问题,比较难以排查,比如:部分cache节点客户证书安装失败,导致客户反馈他们访问提示证书有问题,而我们无法重现。之前还遇到过,因为机房WAF更改规则,导致客户说访问网站提示域名未备案,于是我开发了这个小工具,开发后运维同事一使用,很快就找到了有问题的机房。
工具的使用非常简单,工具目录下新建一个requests.txt,填入如下信息:
url:https://www.baidu.com/
user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
header-output:1
body-output:1
cookie:BIDUPSID=xxxx;
202.108.22.5
180.101.49.11
双击exe文件即可。
简单介绍下工具的参数:
- url: 后面是需要请求的网址,这个参数是必填的
- user-agent:可以自定义http Request UserAgent,可不填,默认是chrome的user agent
- header-output:是否将返回的Respond Header 写入 result 目录下,默认不写入,可不填
- body-output:是否将返回的Respond Body 写入 result 目录下,默认不写入,可不填
- cookie:自定义Request Cookie,可不填
- IP列表,每行一个,如果不填IP,直接DNS域名请求HTTP网址,相当于普通http request。
这个工具,之前的版本,只支持顺序执行,后来我做了一次重构,现在已经支持多IP并发请求。
代码我开源到我的github上了
可以直接git clone下载源码,并使用go build生成可执行文件。
不想自己编译的,也可以通过百度网盘,直接下载可执行文件运行
提取码: f9tt
如果你想在自己的Go代码中,实现指定IP请求http(s)网站,可以参考SimpleHttpTester的源代码,但是SimpleHttpTester的代码经过了一定的封装,剥离起来不太容易,我之前写过一个简单的版本,可以供大家参考:
func RequestIP(requrl string, ip string) error {
urlValue, err := url.Parse(requrl)
if err != nil {
return err
}
host := urlValue.Host
if ip == "" {
ip = host
}
newrequrl := strings.Replace(requrl, host, ip, 1)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{ServerName: host},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse },
Timeout: 5 * time.Second,
}
req, err := http.NewRequest("GET", newrequrl, nil)
if err != nil {
return errors.New(strings.ReplaceAll(err.Error(), newrequrl, requrl))
}
req.Host = host
req.Header.Set("USER-AGENT", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
now := time.Now()
resp, err := client.Do(req)
if err != nil {
return errors.New(strings.ReplaceAll(err.Error(), newrequrl, requrl))
}
defer resp.Body.Close()
fmt.Println("Request IP:" + ip)
fmt.Println("Response Satus:" + resp.Status)
fmt.Printf("Response Time: %.2f秒\n", time.Since(now).Seconds())
fmt.Println()
fmt.Println("----------------------------------")
ip = strings.ReplaceAll(ip, ":", ".")
f, err := os.OpenFile("result/"+ip+"_header.txt", os.O_CREATE|os.O_RDWR, 0777)
if err != nil {
return err
}
defer f.Close()
fmt.Fprintln(f, resp.Status)
resp.Header.Write(f)
f, err = os.OpenFile("result/"+ip+"_body.txt", os.O_CREATE|os.O_RDWR, 0777)
if err != nil {
return err
}
defer f.Close()
io.Copy(f, resp.Body)
return nil
}
来源:oschina
链接:https://my.oschina.net/jamesren/blog/4856139