go http内存泄漏问题分析。
1、https://segmentfault.com/a/1190000020086816
2、demo验证

package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "log" "net/http" _ "net/http/pprof" "net/url" "time" ) type auth struct { Username string `json:"username"` Pwd string `json:"password"` } func main() { //开启pprof协程来进行监控 go func() { log.Println(http.ListenAndServe("0.0.0.0:6060", nil)) }() for { time.Sleep(100 * time.Millisecond) //go postWithJson() go get() } time.Sleep(40 * time.Second) //get() //postWithJson() //postWithUrlencoded() } func get() { //get请求 //http.Get的参数必须是带http://协议头的完整url,不然请求结果为空 resp, _ := http.Get("http://localhost:8080/login2?username=admin&password=123456") //defer resp.Body.Close() // body, _ := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) fmt.Printf("Get request result: %s\n", resp) } func postWithJson() { //post请求提交json数据 auths := auth{"admin", "123456"} ba, _ := json.Marshal(auths) resp, _ := http.Post("http://localhost:8080/login1", "application/json", bytes.NewBuffer([]byte(ba))) //defer resp.Body.Close() //body, _ := ioutil.ReadAll(resp.Body) fmt.Printf("Post request with json result: %s\n", resp) } func postWithUrlencoded() { //post请求提交application/x-www-form-urlencoded数据 form := make(url.Values) form.Set("username", "admin") form.Add("password", "123456") resp, _ := http.PostForm("http://localhost:8080/login2", form) body, _ := ioutil.ReadAll(resp.Body) fmt.Printf("Post request with application/x-www-form-urlencoded result: %s\n", string(body)) }

package main import ( "encoding/json" "log" "net/http" ) func main() { http.HandleFunc("/login1", login1) http.HandleFunc("/login2", login2) http.ListenAndServe("0.0.0.0:8080", nil) } type Resp struct { Code string `json:"code"` Msg string `json:"msg"` } type Auth struct { Username string `json:"username"` Pwd string `json:"password"` } //post接口接收json数据 func login1(writer http.ResponseWriter, request *http.Request) { var auth Auth if err := json.NewDecoder(request.Body).Decode(&auth); err != nil { request.Body.Close() log.Fatal(err) } var result Resp if auth.Username == "admin" && auth.Pwd == "123456" { result.Code = "200" result.Msg = "登录成功" } else { result.Code = "401" result.Msg = "账户名或密码错误" } if err := json.NewEncoder(writer).Encode(result); err != nil { log.Fatal(err) } } //接收x-www-form-urlencoded类型的post请求或者普通get请求 func login2(writer http.ResponseWriter, request *http.Request) { request.ParseForm() username, uError := request.Form["username"] pwd, pError := request.Form["password"] var result Resp if !uError || !pError { result.Code = "401" result.Msg = "登录失败" } else if username[0] == "admin" && pwd[0] == "123456" { result.Code = "200" result.Msg = "登录成功" } else { result.Code = "203" result.Msg = "账户名或密码错误" } if err := json.NewEncoder(writer).Encode(result); err != nil { log.Fatal(err) } }
3、pprof分析下,get/post分别不同场景下的是否resp.Body.Close()的问题
ioutil.ReadAll注意事项:https://blog.csdn.net/xuefeng1207/article/details/87939737
在golang中,实现一个普通的http接口可以处理get请求和x-www-form-urlencoded
类型的post请求,而如果想实现处理json数据的post请求,则需要用另外的方式实现,接收的参数要从request.Body
中读取:
懵懵懂懂,难得糊涂!
潜心所向,无关风月!