使用fasthttp 发起http请求

gogochow · · 2233 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

fasthttp 据说是目前golang性能最好的http库,相对于自带的net/http,性能说是有10倍的提升,具体介绍可以看看官方介绍: [valyala/fasthttp](https://github.com/valyala/fasthttp "fasthttp") 正好最近需要用到,但是发现网上的资料也不是很多,特别是关于client模块的就更少了,只有一些翻译成中文的文档,于是乎就把关于client的代码研究了一下,总结了一些比较简单的使用方法,测试对比net/http是有一定程度的提升,如果需要用到http client似乎fasthttp也是一个不错的选择,当然fasthttp也可以用来做http服务的,不过着并不在此次研究范围内。 顺便也提下他的不足之处吧: 一个是他目前还没有支持http2, 一个是不支持WebSocket,但是WebSocket貌似已经有第三方库的支持了。 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来发起请求呢? emmmm... 好吧!表达能力比较一般,还是直接上代码吧????... 首先肯定是需要安装fasthttp啦 ```shell go get -u github.com/valyala/fasthttp ``` 之后就可以愉快得玩耍了。 先来一波比较简单的,发起一个get请求: ```golang 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请求: ```golang 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或者其他类型。继续看下面: ```golang 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。 ```golang 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中文文档](https://github.com/DavidCai1993/my-blog/issues/35 "fasthttp")

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2233 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传