[Go] Tìm hiểu về keep-alive trong http
keep-alive
cơ bản là giữ kết nối giữa client và server.
Lợi ích
- Giảm kết nối TCP giữa client và server, mỗi client chỉ có duy nhất một kết nối.
- Giảm độ trễ – Việc giảm số lần bắt tay ba bước có thể giúp cải thiện độ trễ của trang web. Điều này đặc biệt đúng với các kết nối SSL/TLS, vốn yêu cầu các chuyến đi khứ hồi bổ sung để mã hóa và xác minh các kết nối.
Code mẫu client và server
Ví dụ 1
Server
package main
import (
"fmt"
"net/http"
)
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Println("receive a request from:", r.RemoteAddr, r.Header)
w.Write([]byte("ok"))
}
func main() {
fmt.Println("server keep alive")
var s = http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(Index),
}
s.ListenAndServe()
}
Client
package main
import (
"fmt"
"io/ioutil"
"net/http"
"time"
)
func main() {
fmt.Println("client keep alive")
c := &http.Client{}
req, err := http.NewRequest("Get", "http://localhost:8080", nil)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", *req)
for i := 0; i < 3; i++ {
resp, err := c.Do(req)
if err != nil {
fmt.Println("http get error:", err)
return
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read body error:", err)
return
}
fmt.Println("response body:", string(b))
time.Sleep(time.Second)
}
}
Kết Quả
- Server:
server keep alive
receive a request from: [::1]:51328 map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
receive a request from: [::1]:51328 map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
receive a request from: [::1]:51328 map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
- Client:
client keep alive
http.Request{Method:"Get", URL:(*url.URL)(0x1400017a000), Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{}, Body:io.ReadCloser(nil), GetBody:(func() (io.ReadCloser, error))(nil), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"localhost:8080", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:(*context.emptyCtx)(0x1400012e008)}
response body: ok
response body: ok
response body: ok
- Có thể thấy, Client đã gọi 3 request và điều chung 1 id
51328
, đồng nghĩa là đã được reuse connection
Ví dụ 2:
Client
- Trong phần tạo ra client, cấu hình disable keep alive:
c := &http.Client{
Transport: &http.Transport{
DisableKeepAlives: true,
},
}
Kết Quả
- Server:
server keep alive
receive a request from: [::1]:51869 map[Accept-Encoding:[gzip] Connection:[close] User-Agent:[Go-http-client/1.1]]
receive a request from: [::1]:51872 map[Accept-Encoding:[gzip] Connection:[close] User-Agent:[Go-http-client/1.1]]
receive a request from: [::1]:51881 map[Accept-Encoding:[gzip] Connection:[close] User-Agent:[Go-http-client/1.1]]
- Client: kêt quả không có gì thay đổi.
- Bây giờ có thể thấy log ở server, mỗi request sẽ có 1 id (51869,51872,51881) khác nhau, đồng nghĩa là connect không được dùng lại.
Ví dụ 3
- Bây giờ việc config keep-alive sẽ do server quyết định Server
func main() {
fmt.Println("server keep alive")
var s = http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(Index),
}
s.SetKeepAlivesEnabled(false)
s.ListenAndServe()
}
Client : không có gì thay đổi.
Kết quả
- Server:
server keep alive
receive a request from: [::1]:52987 map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
receive a request from: [::1]:52991 map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
receive a request from: [::1]:52994 map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/1.1]]
- Client: không có gì thay đổi
- Kết luận là cũng không reuse connection.
Liên Hệ
- facebook: https://www.facebook.com/phucducdev/
- group: https://www.facebook.com/groups/575250507328049
- gmail: ducnp09081998@gmail.com
- linkedin: https://www.linkedin.com/in/phucducktpm/
- hashnode: https://hashnode.com/@OpenDev
- telegram: https://t.me/OpenDevGolang
All rights reserved