前言:在日常的开发工作中,总是避免不了请求外部开放平台接口。那在goLang中,如何处理http请求超时并发起重试
我们可以通过for循环实现重新发起请求的操作:
/**
* 可进行重试的http-post请求方法
* attempts 重试次数
* sleepTime 重试间隔时间 如1为1秒
* postUrl 发送请求的路由
* reqBody 请求参数
*/
func sendPostRetry(attempts int, sleepTime time.Duration, postUrl string, reqBody string) ([]byte,error){
errString := ""
for index := 0; index < attempts; index++ {
res, err := pt.sendPost(postUrl, reqBody)
if err == nil {
return res,nil
}
if index != 0 {
errString += "|" + err.Error()
} else {
errString += err.Error()
}
time.Sleep(sleepTime * time.Duration(2 * index + 1))
}
return nil,errors.New("SendRetry err:" + errString)
}
// 可进行重试的http-post请求方法
func (pt *PiaofutongService) sendPost(postUrl string, reqBody string) ([]byte, error) {
//可以通过client中transport的Dail函数,在自定义Dail函数里面设置建立连接超时时长和发送接受数据超时
client := &http.Client{
Transport: &http.Transport{
Dial: func(netw, addr string) (net.Conn, error) {
conn, err := net.DialTimeout(netw, addr, time.Second*2) //设置建立连接超时
if err != nil {
return nil, err
}
_ = conn.SetDeadline(time.Now().Add(time.Second * 2)) //设置发送接受数据超时
return conn, nil
},
ResponseHeaderTimeout: time.Second * 2,
},
}
//提交请求;用指定的方法,网址,可选的主体放回一个新的*Request
requestDo,err := http.NewRequest("POST",postUrl,strings.NewReader(reqBody))
requestDo.Header.Set("Content-Type","text/xml; charset=UTF-8")
if err != nil {
log.Printf("NewRequest error: %v", err)
return nil, errors.New("httpPost err:" + err.Error())
}
//前面预处理一些参数,状态,Do执行发送;处理返回结果;Do:发送请求,
res,err := client.Do(requestDo)
if nil != err {
log.Printf("httpPost error: %v, url: %v, params: %v\n", err, postUrl, reqBody)
return nil, errors.New("httpPost err:" + err.Error())
}
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
if nil != err {
log.Println("ReadAll err:", err)
return nil, errors.New("ReadAll err:" + err.Error())
}
return data, nil
}