我正在检查服务器的状态。服务器的睡眠时间超过15秒,我正在检查超时。
package main
import (
"fmt"
"net/http"
"time"
)
var urls = []string{
"http://site-centos-64:8080/examples/abc1.jsp",
}
type HttpResponse struct {
url string
response *http.Response
err error
}
var ch = make(chan *HttpResponse, 100) // buffered
var count int
func asyncHttpGets(urls []string) []*HttpResponse {
responses := []*HttpResponse{}
count:=0
timeout := make(chan bool, 100)
for i:=0;i<500;i++{
go func(){
for _, url := range urls {
resp, err := http.Get(url)
count++;
go func() {
time.Sleep(1 * time.Second)
timeout <- true
}()
ch <- &HttpResponse{url, resp, err}
if err != nil {
return
}
resp.Body.Close()
}
}()
}
for {
select {
case r := <-ch:
responses = append(responses, r)
if count == 500 {
return responses
}
case <-timeout:
fmt.Println("Timed Out")
if count == 500 {
return responses
}
}
}
return responses
}
func main() {
now:=time.Now()
results := asyncHttpGets(urls)
for _, result := range results {
fmt.Printf("%s status: %s\n", result.url,result.response.Status)
}
fmt.Println( time.Since(now))
}
但是发生的情况是,最初它会打印“ Timed Out”(超时),但最后的150-200个请求显示“ 200 OK”状态,而不应。另外,当尝试执行1000次操作时,它还会显示“紧急:运行时错误:无效的内存地址或nil指针取消引用”
您正在执行resp, err := http.Get(url)
超时goroutine之前的操作。这将导致一切阻塞,直到响应准备就绪,然后同时在两个通道上发送。
在发送请求之前,只需将启动超时goroutine的行移至该行,就可以了。即:
for _, url := range urls {
go func() {
time.Sleep(1 * time.Second)
timeout <- true
count++;
}()
resp, err := http.Get(url)
count++; //I think this is what you meant, right?
ch <- &HttpResponse{url, resp, err}
if err != nil {
return
}
resp.Body.Close()
}
BTW尝试使用原子增量进行计数,并可能使用一个等待组和一个time.After
通道来代替睡眠。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句