| 
                         使用 sync.Pool 的方式是不是有点怪,主要是 defer 和 api.pool.Put(buffer);buffer = nil  这里解释一下,为了提高 buufer 的复用率会在不使用时尽快把 buffer 放回到缓冲池中,defer 之所以会判断 buffer != nil  主要是在业务逻辑出现错误时,但是 buffer 还没有放回缓冲池时把 buffer 放回到缓冲池,因为在每个错误处理之后都写  api.pool.Put(buffer) 不是一个好的方法,而且容易忘记,但是如果在确定不再使用时 api.pool.Put(buffer);buffer =  nil 就可以尽早把 buffer 放回到缓冲池中,提高复用率,减少新建 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 { 
 -         logrus.WithFields(logrus.Fields{ 
 -             "request": r, 
 -         }).Errorf("jsoniter.Marshal failure: %v", err) 
 -         return nil, fmt.Errorf("jsoniter.Marshal failure: %v", err) 
 -     } 
 -  
 -     data := buffer.Bytes() 
 -     req, err := http.NewRequest("POST", "http://xxx.com", buffer) 
 -     if err != nil { 
 -         logrus.WithFields(logrus.Fields{ 
 -             "data": exbytes.ToString(data), 
 -         }).Errorf("http.NewRequest failed: %v", err) 
 -         return nil, fmt.Errorf("http.NewRequest failed: %v", err) 
 -     } 
 -  
 -     req.Header.Set("User-Agent", "xxx") 
 -  
 -     httpResponse, err := http.DefaultClient.Do(req) 
 -     if httpResponse != nil { 
 -         defer func() { 
 -             io.Copy(ioutil.Discard, httpResponse.Body) 
 -             httpResponse.Body.Close() 
 -         }() 
 -     } 
 -  
 -     if err != nil { 
 -         logrus.WithFields(logrus.Fields{ 
 -             "url": "http://xxx.com", 
 -         }).Errorf("query service failed %v", err) 
 -         return nil, fmt.Errorf("query service failed %v", err) 
 -     } 
 -  
 -     if httpResponse.StatusCode != 200 { 
 -         logrus.WithFields(logrus.Fields{ 
 -             "url":         "http://xxx.com", 
 -             "status":      httpResponse.Status, 
 -             "status_code": httpResponse.StatusCode, 
 -         }).Errorf("invalid http status code") 
 -         return nil, fmt.Errorf("invalid http status code") 
 -     } 
 -  
 -     buffer.Reset() 
 -     _, err = io.Copy(buffer, httpResponse.Body) 
 -     if err != nil { 
 -         return nil, fmt.Errorf("adapter io.copy failure error:%v", err) 
 -     } 
 -  
 -     respData := buffer.Bytes() 
 -     logrus.WithFields(logrus.Fields{ 
 -         "response_json": exbytes.ToString(respData), 
 -     }).Debug("response json") 
 -  
 -     res := &Response{} 
 -     err = jsoniter.Unmarshal(respData, res) 
 -     if err != nil { 
 -         logrus.WithFields(logrus.Fields{ 
 -             "data": exbytes.ToString(respData), 
 -             "url":  "http://xxx.com", 
 -         }).Errorf("adapter jsoniter.Unmarshal failed, error:%v", err) 
 -         return nil, fmt.Errorf("adapter jsoniter.Unmarshal failed, error:%v", err) 
 -     } 
 -      
 -     api.pool.Put(buffer) 
 -     buffer = nil 
 -  
 -     // ... 
 -     return res, nil 
 - } 
 
                          (编辑:泰州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |