Golang http连接无限期地持续

问题描述:

我有一个简单的代码从数据库中检索数据,我正在使用Jmeter对它进行负载测试。我所做的是模拟1,000次请求,有时我得到所有1,000次成功的请求,有时我得到999次请求,我必须停止它,因为它看起来像线程或最后的结果一直持续下去,这是它的外观,注意如何最后的请求需要超过正常时间的10倍以上。如果我不阻止它,那么这个请求会继续下去。 enter image description hereGolang http连接无限期地持续

这是我的代码

func get_data(w http.ResponseWriter, r *http.Request) { 
    var result string 
    r.ParseForm() 

    wg := sync.WaitGroup{} 

    wg.Add(1) 
    go func() { 

     defer wg.Done() 

     db.QueryRow("select json_build_object('Locations', array_to_json(array_agg(t))) from (SELECT latitudes,county,longitudes,"+ 
      "statelong,thirtylatmin,thirtylatmax,thirtylonmin,thirtylonmax,city"+ 
      " FROM zips where city='Orlando' ORDER BY city limit 5) t").Scan(&result) 

    }() 
    wg.Wait() 

    fmt.Fprintf(w,result) 
} 

然后,我有我的数据库连接

var db *sql.DB 

func init() { 
    var err error 
    db, err = sql.Open("postgres", Postgres_Connect) 
    if err != nil { 
     log.Fatal("Invalid DB config:", err) 
     println("Invalid DB config:") 
     //log_errors("HomePage-Postgres: error opening database",err) 
    } 
    if err = db.Ping(); err != nil { 
     log.Fatal("DB unreachable:", err) 
     println() 
    } 



} 

,这里是我的HTTP服务器

func main() { 

    runtime.GOMAXPROCS(runtime.NumCPU()) 
    r := mux.NewRouter() 

    r.HandleFunc("/mydata",Controllers.Get_Data) 
    http.Handle("/",r) 


    srv := &http.Server{ 
     ReadTimeout: 20 * time.Second, 
     WriteTimeout: 20 * time.Second, 
     IdleTimeout: 120 * time.Second, 
     Addr: ":8000", 
    } 
    log.Println(srv.ListenAndServe()) 
} 

我希望在ReadTimeOut会杀死连接,但似乎没有

+1

我不知道是什么导致了问题,但我没有发现它和代码的一些问题。 1)'get_data'中的goroutine不是必需的。直接从处理程序中查询数据库。 2)'result'用作格式字符串。使用'io.WriteString(w,result)'而不是'fmt.Printf'。 –

ReadTimeOut适用于读取由通过net/http的服务器代码,而不是执行请求的够程:

ReadTimeout是用于读取的整个 请求,包括body.`

的最大持续时间

一旦请求被读取,该值不再使用,处理程序负责决定事情是否超时。

如果要在数据库查询完成之前取消HTTP请求,可以使用context.Context执行此操作。

扩展req.Context,加timeout or deadline,通过这个新的背景下sql.QueryRowContext

ctx, _ := context.WithTimeout(r.Context(), 20 * time.Second) 

db.QueryRowContext(ctx, "select json_build_object('Locations', array_to_json(array_agg(t))) from (SELECT latitudes,county,longitudes,"+ 
    "statelong,thirtylatmin,thirtylatmax,thirtylonmin,thirtylonmax,city"+ 
    " FROM zips where city='Orlando' ORDER BY city limit 5) t").Scan(&result)