goroutine和Http请求中的超时

Harshit:

我正在检查服务器的状态。服务器的睡眠时间超过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指针取消引用”

Not_a_Golfer:

您正在执行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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章