golang使用fasthttp 發起http請求

fasthttp 聽說是目前golang性能最好的http庫,相對於自帶的net/http,性能說是有10倍的提高,具體介紹能夠看看官方介紹: valyala/fasthttphtml

正好最近須要用到,可是發現網上的資料也不是不少,特別是關於client模塊的就更少了,只有一些翻譯成中文的文檔,因而乎就把關於client的代碼研究了一下,總結了一些比較簡單的使用方法,測試對比net/http是有必定程度的提高,若是須要用到http client彷佛fasthttp也是一個不錯的選擇,固然fasthttp也能夠用來作http服務的,不過着並不在這次研究範圍內。git

順便也提下他的不足之處吧: 一個是他目前尚未支持http2, 一個是不支持WebSocket,可是WebSocket貌似已經有第三方庫的支持了。github

fasthttp截至目前爲止的todo list:golang

OK,言歸正傳,如何更高效得使用fasthttp來發起請求呢? emmmm... 好吧!表達能力比較通常,仍是直接上代碼吧😂...shell

首先確定是須要安裝fasthttp啦json

go get -u github.com/valyala/fasthttp
複製代碼

以後就能夠愉快得玩耍了。cookie

先來一波比較簡單的,發起一個get請求:app

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請求: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實現了get和post請求,這兩個方法也已經實現了自動重定向,那麼若是有更復雜的請求或須要手動重定向,須要怎麼處理呢?好比有些API服務須要咱們提供json body或者xml body也就是,Content-Type是application/json、application/xml或者其餘類型。繼續看下面:性能

func main() {
	url := `http://httpbin.org/post?key=123`
	
	req := &fasthttp.Request{}
	req.SetRequestURI(url)
	
	requestBody := []byte(`{"request":"test"}`)
	req.SetBody(requestBody)

	// 默認是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還有優化的空間有木有? 有文章說到它的高性能主要源自於「複用」,經過服務協程和內存變量的複用,節省了大量資源分配的成本。 好吧。。。 繼續優化下。。 翻閱文檔發現了他提供了幾個方法:AcquireRequest()AcquireResponse(),並且也推薦了在有性能要求的代碼中,經過 AcquireRequest 和 AcquireResponse 來獲取 req 和 resp。

func main() {
	url := `http://httpbin.org/post?key=123`

	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	defer func(){
	    // 用完須要釋放資源
	    fasthttp.ReleaseResponse(resp) 
	    fasthttp.ReleaseRequest(req)
	}()
	
	// 默認是application/x-www-form-urlencoded
	req.Header.SetContentType("application/json")
	req.Header.SetMethod("POST")
	
	req.SetRequestURI(url)
	
	requestBody := []byte(`{"request":"test"}`)
	req.SetBody(requestBody)

	if err := fasthttp.Do(req, resp); err != nil {
		fmt.Println("請求失敗:", err.Error())
		return
	}

	b := resp.Body()

	fmt.Println("result:\r\n", string(b))
}
複製代碼

通過這樣簡單的改動,性能上確實是增長了一些。

關於fasthttp的文檔,若是英文不太好的同窗能夠考慮看看中文翻譯版,地址:fasthttp中文文檔

相關文章
相關標籤/搜索