| 
                         哇塞 bytes.makeSlice 终于从前十中消失了,真的太棒了,还是看看 bytes.makeSlice 的其它调用情况吧。 
- (pprof) web bytes.makeSlice 
 
  
  
从图中可以发现 bytes.makeSlice 的分配已经很小了, 且大多数是 http.Request.ParseForm 读取  http.Request.Body 使用 ioutil.ReadAll 原因,这次优化的效果非常的好。 
看一下更直观的火焰图吧,和优化前对比一下很明显 ioutil.ReadAll 看不到了。 
  
优化期间遇到的问题 
比较惭愧在优化的过程出现了一个过失,导致生产环境2分钟故障,通过自动部署立即回滚才得以快速恢复,之后分析代码解决之后上线才完美优化,下面总结一下出现的问题吧。 
在构建 http 请求时我分了两个部分优化,序列化 json 和读取 http.Response.Body 数据,保持一个观点就是尽早把 buffer  放回到缓冲池,因为 http.DefaultClient.Do(req) 是网络请求会相对耗时,在这个之前我把 buffer 放回到缓冲池中,之后读取  http.Response.Body 时在重新获取一个 buffer,大概代码如下: 
- package adapter 
 -  
 - import ( 
 -     "bytes" 
 -     "fmt" 
 -     "io" 
 -     "io/ioutil" 
 -     "net/http" 
 -     "sync" 
 -  
 -     "github.com/json-iterator/go" 
 -     "github.com/sirupsen/logrus" 
 -     "github.com/thinkeridea/go-extend/exbytes" 
 - ) 
 -  
 - type Adapter struct { 
 -     pool sync.Pool 
 - } 
 -  
 - func New() *Adapter { 
 -     return &Adapter{ 
 -         pool: sync.Pool{ 
 -             New: func() interface{} { 
 -                 return bytes.NewBuffer(make([]byte, 4096)) 
 -             }, 
 -         }, 
 -     } 
 - } 
 -  
 - func (api *Adapter) Request(r *Request) (*Response, error) { 
 -     var err error 
 -     buffer := api.pool.Get().(*bytes.Buffer) 
 -     buffer.Reset() 
 -     defer func() { 
 -         if buffer != nil { 
 -             api.pool.Put(buffer) 
 -             buffer = nil 
 -         } 
 -     }() 
 -  
 -     e := jsoniter.NewEncoder(buffer) 
 -     err = e.Encode(r) 
 -     if err != nil { 
 -         return nil, fmt.Errorf("jsoniter.Marshal failure: %v", err) 
 -     } 
 -  
 -     data := buffer.Bytes() 
 -     req, err := http.NewRequest("POST", "http://xxx.com", buffer) 
 -     if err != nil { 
 -         return nil, fmt.Errorf("http.NewRequest failed: %v", err) 
 -     } 
 -  
 -     req.Header.Set("User-Agent", "xxx") 
 -  
 -     api.pool.Put(buffer) 
 -     buffer = nil 
 -      
 -     httpResponse, err := http.DefaultClient.Do(req) 
 -      
 -      
 -     // .... 
 -  
 -     buffer = api.pool.Get().(*bytes.Buffer) 
 -     buffer.Reset() 
 -     defer func() { 
 -         if buffer != nil { 
 -             api.pool.Put(buffer) 
 -             buffer = nil 
 -         } 
 -     }() 
 -     _, err = io.Copy(buffer, httpResponse.Body) 
 -     if err != nil { 
 -         return nil, fmt.Errorf("adapter io.copy failure error:%v", err) 
 -     } 
 -  
 -     // .... 
 -      
 -     api.pool.Put(buffer) 
 -     buffer = nil 
 -  
 -     // ... 
 -     return res, nil 
 - } 
 
                          (编辑:滁州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |