fasthttp 據(jù)說是目前golang性能最好的http庫捕传,相對于自帶的net/http西土,性能說是有10倍的提升,具體介紹可以看看官方介紹: valyala/fasthttp
正好最近需要用到,但是發(fā)現(xiàn)網(wǎng)上的資料也不是很多凄鼻,特別是關(guān)于client模塊的就更少了,只有一些翻譯成中文的文檔,于是乎就把關(guān)于client的代碼研究了一下块蚌,總結(jié)了一些比較簡單的使用方法闰非,測試對比net/http是有一定程度的提升,如果需要用到http client似乎fasthttp也是一個不錯的選擇峭范,當(dāng)然fasthttp也可以用來做http服務(wù)的财松,不過著并不在此次研究范圍內(nèi)。
順便也提下他的不足之處吧: 一個是他目前還沒有支持http2, 一個是不支持WebSocket,但是WebSocket貌似已經(jīng)有第三方庫的支持了纱控。
fasthttp截至目前為止的todo list:
- SessionClient with referer and cookies support.
- ProxyHandler similar to FSHandler.
- WebSockets. See https://tools.ietf.org/html/rfc6455 .
- HTTP/2.0. See https://tools.ietf.org/html/rfc7540 .
OK辆毡,言歸正傳,如何更高效得使用fasthttp來發(fā)起請求呢甜害?
emmmm... 好吧舶掖!表達(dá)能力比較一般,還是直接上代碼吧??...
首先肯定是需要安裝fasthttp啦
go get -u github.com/valyala/fasthttp
之后就可以愉快得玩耍了尔店。
先來一波比較簡單的眨攘,發(fā)起一個get請求:
package main
import (
"github.com/valyala/fasthttp"
)
func main() {
url := `http://httpbin.org/get`
status, resp, err := fasthttp.Get(nil, url)
if err != nil {
fmt.Println("請求失敗:", err.Error())
return
}
if status != fasthttp.StatusOK {
fmt.Println("請求沒有成功:", status)
return
}
fmt.Println(string(resp))
}
再來一個Post請求:
func main() {
url := `http://httpbin.org/post?key=123`
// 填充表單,類似于net/url
args := &fasthttp.Args{}
args.Add("name", "test")
args.Add("age", "18")
status, resp, err := fasthttp.Post(nil, url, args)
if err != nil {
fmt.Println("請求失敗:", err.Error())
return
}
if status != fasthttp.StatusOK {
fmt.Println("請求沒有成功:", status)
return
}
fmt.Println(string(resp))
}
上面兩個簡單的demo實(shí)現(xiàn)了get和post請求嚣州,這兩個方法也已經(jīng)實(shí)現(xiàn)了自動重定向鲫售,那么如果有更復(fù)雜的請求或需要手動重定向,需要怎么處理呢避诽?比如有些API服務(wù)需要我們提供json body或者xml body也就是龟虎,Content-Type是application/json、application/xml或者其他類型沙庐。繼續(xù)看下面:
func main() {
url := `http://httpbin.org/post?key=123`
req := &fasthttp.Request{}
req.SetRequestURI(url)
requestBody := []byte(`{"request":"test"}`)
req.SetBody(requestBody)
// 默認(rèn)是application/x-www-form-urlencoded
req.Header.SetContentType("application/json")
req.Header.SetMethod("POST")
resp := &fasthttp.Response{}
client := &fasthttp.Client{}
if err := client.Do(req, resp);err != nil {
fmt.Println("請求失敗:", err.Error())
return
}
b := resp.Body()
fmt.Println("result:\r\n", string(b))
}
搞定鲤妥,這樣就完成了,but還有優(yōu)化的空間有木有拱雏?
有文章說到它的高性能主要源自于“復(fù)用”棉安,通過服務(wù)協(xié)程和內(nèi)存變量的復(fù)用,節(jié)省了大量資源分配的成本铸抑。
好吧贡耽。。鹊汛。 繼續(xù)優(yōu)化下蒲赂。。
翻閱文檔發(fā)現(xiàn)了他提供了幾個方法:AcquireRequest()
刁憋、AcquireResponse()
,而且也推薦了在有性能要求的代碼中滥嘴,通過 AcquireRequest 和 AcquireResponse 來獲取 req 和 resp。
func main() {
url := `http://httpbin.org/post?key=123`
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req) // 用完需要釋放資源
// 默認(rèn)是application/x-www-form-urlencoded
req.Header.SetContentType("application/json")
req.Header.SetMethod("POST")
req.SetRequestURI(url)
requestBody := []byte(`{"request":"test"}`)
req.SetBody(requestBody)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp) // 用完需要釋放資源
if err := fasthttp.Do(req, resp); err != nil {
fmt.Println("請求失敗:", err.Error())
return
}
b := resp.Body()
fmt.Println("result:\r\n", string(b))
}
經(jīng)過這樣簡單的改動至耻,性能上確實(shí)是增加了一些若皱。
關(guān)于fasthttp的文檔镊叁,如果英文不太好的同學(xué)可以考慮看看中文翻譯版,地址:fasthttp中文文檔