加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

优雅的读取http哀求或相应的数据

发布时间:2019-01-28 13:03:14 所属栏目:教程 来源:戚银
导读:从 http.Request.Body 或 http.Response.Body 中读取数据要领或者许多,尺度库中大大都行使 ioutil.ReadAll 要领一次读取全部数据,假如是 json 名目标数据还可以行使 json.NewDecoder 从 io.Reader 建设一个理会器,倘使行使 pprof 来说明措施老是会发明

哇塞 bytes.makeSlice 终于以前十中消散了,真的太棒了,照旧看看 bytes.makeSlice 的其余挪用环境吧。

  1. (pprof) web bytes.makeSlice 

优雅的读取http哀求或相应的数据

从图中可以发明 bytes.makeSlice 的分派已经很小了, 且大大都是 http.Request.ParseForm 读取 http.Request.Body 行使 ioutil.ReadAll 缘故起因,这次优化的结果很是的好。

看一下更直观的火焰图吧,和优化前比拟一下很明明 ioutil.ReadAll 看不到了。

优雅的读取http哀求或相应的数据

优化时代碰着的题目

较量忸怩在优化的进程呈现了一个纰谬,导致出产情形2分钟妨碍,通过自动陈设当即回滚才得以快速规复,之后说明代码办理之后上线才美满优化,下面总结一下呈现的题目吧。

在构建 http 哀求时我分了两个部门优化,序列化 json 和读取 http.Response.Body 数据,保持一个概念就是尽早把 buffer 放回到缓冲池,由于 http.DefaultClient.Do(req) 是收集哀求会相对耗时,在这个之前我把 buffer 放回到缓冲池中,之后读取 http.Response.Body 时在从头获取一个 buffer,或许代码如下:

  1. package adapter 
  2.  
  3. import ( 
  4.     "bytes" 
  5.     "fmt" 
  6.     "io" 
  7.     "io/ioutil" 
  8.     "net/http" 
  9.     "sync" 
  10.  
  11.     "github.com/json-iterator/go" 
  12.     "github.com/sirupsen/logrus" 
  13.     "github.com/thinkeridea/go-extend/exbytes" 
  14.  
  15. type Adapter struct { 
  16.     pool sync.Pool 
  17.  
  18. func New() *Adapter { 
  19.     return &Adapter{ 
  20.         pool: sync.Pool{ 
  21.             New: func() interface{} { 
  22.                 return bytes.NewBuffer(make([]byte, 4096)) 
  23.             }, 
  24.         }, 
  25.     } 
  26.  
  27. func (api *Adapter) Request(r *Request) (*Response, error) { 
  28.     var err error 
  29.     buffer := api.pool.Get().(*bytes.Buffer) 
  30.     buffer.Reset() 
  31.     defer func() { 
  32.         if buffer != nil { 
  33.             api.pool.Put(buffer) 
  34.             buffer = nil 
  35.         } 
  36.     }() 
  37.  
  38.     e := jsoniter.NewEncoder(buffer) 
  39.     err = e.Encode(r) 
  40.     if err != nil { 
  41.         return nil, fmt.Errorf("jsoniter.Marshal failure: %v", err) 
  42.     } 
  43.  
  44.     data := buffer.Bytes() 
  45.     req, err := http.NewRequest("POST", "http://xxx.com", buffer) 
  46.     if err != nil { 
  47.         return nil, fmt.Errorf("http.NewRequest failed: %v", err) 
  48.     } 
  49.  
  50.     req.Header.Set("User-Agent", "xxx") 
  51.  
  52.     api.pool.Put(buffer) 
  53.     buffer = nil 
  54.      
  55.     httpResponse, err := http.DefaultClient.Do(req) 
  56.      
  57.      
  58.     // .... 
  59.  
  60.     buffer = api.pool.Get().(*bytes.Buffer) 
  61.     buffer.Reset() 
  62.     defer func() { 
  63.         if buffer != nil { 
  64.             api.pool.Put(buffer) 
  65.             buffer = nil 
  66.         } 
  67.     }() 
  68.     _, err = io.Copy(buffer, httpResponse.Body) 
  69.     if err != nil { 
  70.         return nil, fmt.Errorf("adapter io.copy failure error:%v", err) 
  71.     } 
  72.  
  73.     // .... 
  74.      
  75.     api.pool.Put(buffer) 
  76.     buffer = nil 
  77.  
  78.     // ... 
  79.     return res, nil 

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读