如果我在执行HTTP请求时添加客户端超时,实际上会发生什么?
我的代码就是这样
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"sync"
"time"
"github.com/vbauerster/mpb"
"github.com/vbauerster/mpb/decor"
)
type response struct {
Header header `json:"header"`
// Data data `json:"data"`
}
type header struct {
TotalData int `json:"total_data"`
}
type data struct {
Product []products `json:"products"`
}
type products struct {
Ads ads `json:"ads"`
}
type ads struct {
ID string `json:"id"`
}
func main() {
var wg sync.WaitGroup
empty1 := 0
empty2 := 0
empty3 := 0
loop := 1000
endpoint := ""
file, _ := os.OpenFile("file.tmp", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
log.SetOutput(file)
p := mpb.New(mpb.WithWaitGroup(&wg))
wg.Add(3)
bar := p.AddBar(int64(loop),
// override DefaultBarStyle, which is "[=>-]<+"
mpb.BarStyle("╢▌▌░╟"),
mpb.PrependDecorators(
decor.Name("PB1", decor.WC{W: 3 + 1, C: decor.DidentRight}),
decor.CountersNoUnit("%d / %d", decor.WCSyncWidth),
),
mpb.AppendDecorators(decor.Percentage(decor.WC{W: 5}),
decor.OnComplete(
// ETA decorator with ewma age of 60
decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
),
),
)
bar2 := p.AddBar(int64(loop),
// override DefaultBarStyle, which is "[=>-]<+"
mpb.BarStyle("╢▌▌░╟"),
mpb.PrependDecorators(
decor.Name("PB2", decor.WC{W: 3 + 1, C: decor.DidentRight}),
decor.CountersNoUnit("%d / %d", decor.WCSyncWidth),
),
mpb.AppendDecorators(decor.Percentage(decor.WC{W: 5}),
decor.OnComplete(
// ETA decorator with ewma age of 60
decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
),
),
)
bar3 := p.AddBar(int64(loop),
// override DefaultBarStyle, which is "[=>-]<+"
mpb.BarStyle("╢▌▌░╟"),
mpb.PrependDecorators(
decor.Name("PB3", decor.WC{W: 3 + 1, C: decor.DidentRight}),
decor.CountersNoUnit("%d / %d", decor.WCSyncWidth),
),
mpb.AppendDecorators(decor.Percentage(decor.WC{W: 5}),
decor.OnComplete(
// ETA decorator with ewma age of 60
decor.EwmaETA(decor.ET_STYLE_GO, 60), "done",
),
),
)
go func() {
defer wg.Done()
now := time.Now()
conChan := make(chan response, loop)
var wg2 sync.WaitGroup
wg2.Add(1)
go func() {
defer wg2.Done()
for i := 1; i <= loop; i++ {
receiver := <-conChan
if receiver.Header.TotalData == 0 {
empty1++
}
bar.Increment()
}
}()
for i := 1; i <= loop; i++ {
if i%50 == 0 {
time.Sleep(1 * time.Second)
}
go concurent(conChan, fmt.Sprintf(endpoint, i))
}
wg2.Wait()
log.Println("wg 1", time.Since(now).Seconds())
}()
go func() {
defer wg.Done()
now := time.Now()
conChan := make(chan response, loop)
var wg2 sync.WaitGroup
wg2.Add(1)
go func() {
defer wg2.Done()
for i := 1; i <= loop; i++ {
receiver := <-conChan
if receiver.Header.TotalData == 0 {
empty2++
}
bar2.Increment()
}
}()
for i := 1; i <= loop; i++ {
if i%50 == 0 {
time.Sleep(1 * time.Second)
}
go concurent(conChan, fmt.Sprintf(endpoint, i))
}
wg2.Wait()
log.Println("wg 2", time.Since(now).Seconds())
}()
go func() {
defer wg.Done()
now := time.Now()
conChan := make(chan response, loop)
var wg2 sync.WaitGroup
wg2.Add(1)
go func() {
defer wg2.Done()
for i := 1; i <= loop; i++ {
receiver := <-conChan
if receiver.Header.TotalData == 0 {
empty3++
}
bar3.Increment()
}
}()
for i := 1; i <= loop; i++ {
if i%50 == 0 {
time.Sleep(1 * time.Second)
}
go concurent(conChan, fmt.Sprintf(endpoint, i))
}
wg2.Wait()
log.Println("wg 3", time.Since(now).Seconds())
}()
p.Wait()
fmt.Println("empty1:", empty1)
fmt.Println("empty2:", empty2)
fmt.Println("empty3:", empty3)
}
func concurent(channel chan response, url string) {
resp := response{}
defer func() {
channel <- resp
}()
client := &http.Client{
Timeout: 500 * time.Millisecond,
}
req, err := http.NewRequest("GET", url, nil)
res, err := client.Do(req)
if err != nil {
log.Print(err, "1")
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Print(err, "2")
return
}
err = json.Unmarshal(body, &resp)
if err != nil {
log.Print(string(body))
return
}
}
我很困惑,因为如果我不设置超时,那么在设置超时的情况下,如果执行相同的时间执行,我将得到更少的空结果,在这种情况下为500ms。 (大约20秒即可完成所有过程,无论有无超时)。在Go文档中说
客户端的传输通常具有内部状态(缓存的TCP 连接),因此应重新使用客户端,而不是根据需要创建客户端。客户端可以安全地被多个goroutine并发使用。
这是什么意思?我用于请求的客户端是否相同,这就是为什么设置超时时得到更多空结果的原因?