2017-05-18 3 views
2

Ich habe einen einfachen Code, der Daten aus der Datenbank abruft, und ich verwende Jmeter, um darauf Lasttests durchzuführen. Was ich tue, ist die Simulation von 1.000 Anfragen, manchmal bekomme ich alle 1.000 erfolgreichen Anfragen und manchmal bekomme ich 999 Anfragen und ich muss sie stoppen, weil der Thread oder die letzten Ergebnisse scheinbar unbegrenzt weiterlaufen Die letzte Anforderung dauert mehr als das Zehnfache der normalen Zeit. Wenn ich es nicht aufhöre, würde diese Anfrage weiter und weiter gehen. enter image description hereGolang HTTP-Verbindung besteht für unbegrenzte Zeit

Dies ist mein Code

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) 
} 

Dann

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() 
    } 



} 

meine Datenbank-Verbindung Ich habe und hier Server meine 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()) 
} 

Ich war, dass die Readtimeout gehofft, würde Töte die Verbindung, aber es scheint, als ob es nicht funktioniert

+1

Ich weiß nicht, was das Problem verursacht, aber ich habe ein paar Probleme mit dem Code bemerken. 1) Die goroutine in 'get_data' ist nicht erforderlich. Fragen Sie die Datenbank direkt vom Handler ab. 2) Das 'result' wird als Formatzeichenfolge verwendet. Verwenden Sie 'io.WriteString (w, result)' anstelle von 'fmt.Printf'. –

Antwort

2

ReadTimeOut gilt für die von net/http ‚s Servercode aus liest, die Anforderung nicht auf das goroutine ausführen:

Readtimeout ist die maximale Dauer des gesamten Anforderung für das Lesen, einschließlich der body.`

Sobald die Anforderung gelesen wurde, wird dieser Wert nicht mehr verwendet, und der Handler ist verantwortlich für die Entscheidung, ob die Zeit abgelaufen ist oder nicht.

Wenn Sie die HTTP-Anfrage abbrechen möchten, bevor die Datenbankabfrage abgeschlossen ist, können Sie dies mit einem context.Context tun.

req.Context verlängern, fügen Sie ein timeout or deadline, diesen neuen Kontext sql.QueryRowContext zu übergeben:

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)