在go lang

时间:2016-02-12 10:22:12

标签: go profiling pprof

我正在尝试描述用go编写的http处理程序。在每个http请求中从S3下载图像,调整大小/裁剪它并将其写入响应。

我已经关注了这个link并尝试使用简单方法和硬方法来描述我的代码。现在,当我使用代码中提到的以下行时。

defer profile.Start(profile.CPUProfile).Stop() 

它不会在/tmp/profie[some number]/cpu.pprof文件

中写任何内容
func main() {                                    

       defer profile.Start(profile.CPUProfile).Stop()   

      if err := http.ListenAndServe(":8081", http.HandlerFunc(serveHTTP)); err != nil {
       logFatal("Error when starting or running http server: %v", err)
    }       
}

func serveHTTP(w http.ResponseWriter, r *http.Request) {
        keyName := r.URL.Path[1:]
        s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
        params := &s3.GetObjectInput{
        Bucket: aws.String(bucketName),
        Key: aws.String(keyName),
        }

    mw := imagick.NewMagickWand()
    defer mw.Destroy()
    ...
}

此外,当我使用defer profile.Start(profile.CPUProfile).Stop()内的serveHTTP行时:

func serveHTTP(w http.ResponseWriter, r *http.Request) {

    defer profile.Start(profile.CPUProfile).Stop()
    ......
}

它会在/tmp/profile[some number]文件夹中创建多个文件。所以,第一个问题是为什么它不是在文件中写入,其次不应该是serveHTTP method内的位置,因为服务器只会启动一次。因此,main()将在每次请求被调用serveHTTP时被调用。

第1部分

 .               124:   s3Client := s3.New(session.New(), &aws.Config{Region: aws.String(region)})
 .          .    125:        params := &s3.GetObjectInput{
 .          .    126:       Bucket: aws.String(masterBucketName),
 .          .    127:       Key: aws.String(keyName),
 .    32.01kB    128:       }
 .          .    129:
 .          .    130:   mw := imagick.NewMagickWand()
 .          .    131:   defer mw.Destroy()
 .          .    132:   
 .          .    133:   out, err := s3Client.GetObject(params)          
 .          .    134:
 .          .    135:   if strings.EqualFold(keyName[strings.LastIndex(keyName,".")+1:len(keyName)], "gif") {
 .          .    136:
 .    40.11kB    137:       blobGiff, err := ioutil.ReadAll(out.Body)
 .          .    138:       w.Header().Set("Content-Type", "image/gif")
 .          .    139:       w.Header().Set("Cache-Control", "max-age: 604800, public")  
 .          .    140:       w.Header().Set("Last-Modified", time.Now().Format(http.TimeFormat))
 .          .    141:       w.Header().Set("Expires", time.Now().AddDate(1, 0, 0).Format(http.TimeFormat))  
 .          .    142:

第2部分:

                                   else {
         .          .    167:       img, err := ioutil.ReadAll(out.Body)
         .          .    168:       if err != nil {
         .          .    169:          
         .          .    170:          w.WriteHeader(http.StatusNotFound) 
         .     1.56MB    171:          return      
         .          .    172:       }   

另外,在上面两部分中,第128,137和171行有内存泄漏,对吗?另外,我找不到关闭/销毁s3ClientblobGiff(byte [])的任何选项。

2 个答案:

答案 0 :(得分:4)

要在http服务器运行时对其进行配置,您可以使用net/http/pprof包。

添加

procedure TForm1.cxGrid1DBTableView1EditKeyPress(Sender:
    TcxCustomGridTableView; AItem: TcxCustomGridTableItem; AEdit:
    TcxCustomEdit; var Key: Char);
var
  AField : TField;
  strValue : String;
  V : Variant;
  i,
  InsertPoint,
  EC : Integer;

  function CharIsOK(Ch : Char) : Boolean;
  begin
    Result := CharInSet(Ch, ['0', '1', '2', '3', '4', '5', '6',
                        '7', '8', '9', '-', '+']);
    // Or Result := Ch in ['0', ... for Delphi prior to D2009
  end;

begin
  if AItem = cxGrid1DBTableView1Value then begin
    //  The following manually cleans up input into a TIntegerField column
    // whose Properties is set to TextEdit

    // First, pick up the text in the inplace editor
    V := AEdit.EditingValue;
    if not VarIsNull(V) then
      strValue := AEdit.EditingValue
    else
      strValue := '';

    if strValue <> '' then begin
      //  Next, check that the Key is a valid one for an Integer field.
      if CharIsOk(Key) then begin
      //  The fact that the Key is a valid character for an Integer field
      //  does not in itself guarantee that the entire editing string, including the Key
      //  which is about to be added to in, is a valid string representation of an integer,
      //  e.g. it might be '--', '+1-5', etc
      //  So, we add the Key to the existing editing string and see if it converts to an integer
      //  Of course, there is the wrinkle that the caret may not be at the end of the editing text
      //  so we need to find out where the caret is.  First we need 
      //  to check that AEdit is a TcxtextEdit so that we can access
      // its SelStart property
        Assert(AEdit is TcxTextEdit);
        InsertPoint := TcxTextEdit(AEdit).SelStart;
        Insert(Key, strValue, InsertPoint + 1);
        Val(strValue, i, EC);
        //  if EC is non-zero, the conversion failed, so we suppress the Key
        if EC <> 0 then
          Key := Chr(0);
       end
       else
         //  the Key might be a backspace, so permit that
         if Ord(Key) <> VK_Back then
           Key := Chr(0);
    end
  end;
end;

导入并在浏览器中打开import _ "net/http/pprof"

答案 1 :(得分:2)

首先使用import "net/http/pprof" NOT import _“net / http / pprof 。后来人们无法识别以下路线中的pprof

我使用的是默认的serveMux / multiplexer。但后来我创建了自己的,因为人们认为它具有性能含义。

myMux := http.NewServeMux()

然后添加了请求的路由

myMux.HandleFunc("/", serveHTTP)

另外,我还添加了使http://localhost:8081/debug/pprof/工作的路线

        myMux.HandleFunc("/debug/pprof/", pprof.Index)
        myMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
        myMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
        myMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)

所以,最终的代码是:

导入“net / http / pprof

func main() {                                    

        myMux := http.NewServeMux()
        myMux.HandleFunc("/", serveHTTP)

        myMux.HandleFunc("/debug/pprof/", pprof.Index)
        myMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
        myMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
        myMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)   

    if err := http.ListenAndServe(":8081", myMux); err != nil {
        logFatal("Error when starting or running http server: %v", err)
    }       

}