2017-07-07 3 views
0

Ich habe ein paar Bilder, die ich mit dem offiziellen Amazon S3-Paket auf meinen s3-Account hochlade. Meine Bilder sind in der Regel 250 - 350 KB, also kleine Bilder, aber sie brauchen etwa 8 oder 9 Sekunden zum Hochladen, was übertrieben erscheint, alle Vorschläge zur Verbesserung der Geschwindigkeit wären großartig. Dies ist mein Code und wenn ich den Bildcode für die Größenänderung abnehme, dauert es immer noch gut 8 oder 9 Sekunden.Golang amazon s3 wie kann ich Bilder schneller hochladen

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


      r.ParseForm() 
    var buff bytes.Buffer 


    wg := sync.WaitGroup{} 

    wg.Add(1) 
    go func() { 
     defer wg.Done() 

     var buf bytes.Buffer 
     sess, _ := session.NewSession(&aws.Config{ 
      Region:  aws.String("us-west-2"), 
      Credentials: credentials.NewStaticCredentials(aws_access_key_id, aws_secret_access_key, ""), 

     }) 

     svc := s3.New(sess) 

     file, handler, err := r.FormFile("file") 
     if err != nil { 
      log_errors(" error on upload",err.Error(),w) 
      fmt.Println("Error Uploading Image") 
      return 
     } 
     defer file.Close() 

     img,err := imaging.Decode(file) 
     if err != nil { 
      print("Imaging Open error") 
      log_errors("Error decoding",err.Error(),w) 
      return 
     } 

       imgSize,err := strconv.Atoi(r.FormValue("imgsize")) 

     if err != nil { 
      println("Error converting to integer") 
      log_errors("Error converting to integer",err.Error(),w) 
      return 
     } 

     b := img.Bounds() 
     heightImg := b.Max.Y 
     widthImg := b.Max.X 


     // resize image 
     height := int(float64(heightImg) * .23) 
     width := int(float64(widthImg) * .23) 


     if imgSize < 401 { 
      height = int(float64(heightImg) * 1) 
      width = int(float64(widthImg) * 1) 

     } else if imgSize >= 401 && imgSize < 900 { 
       height = int(float64(heightImg) * .68) 
       width = int(float64(widthImg) * .68) 
       println("Middle Image") 
        } else if imgSize >= 900 && imgSize < 1300 { 
      height = int(float64(heightImg) * .45) 
      width = int(float64(widthImg) * .45) 
      } else if imgSize >= 1301 && imgSize < 1700 { 
      height = int(float64(heightImg) * .40) 
      width = int(float64(widthImg) * .40) 
     } 


     new_img := imaging.Resize(img,width,height, imaging.Lanczos) 
     // end resize 

     err = imaging.Encode(&buf,new_img, imaging.JPEG) 
     if err != nil { 
      log.Println(err) 
      log_errors(" error encoding file",err.Error(),w) 
         return 
     } 


     r := bytes.NewReader(buf.Bytes()) 



     read_file,err := ioutil.ReadAll(r) 
     if err != nil { 
      fmt.Println("Error Reading file") 
      log_errors(" error reading file",err.Error(),w) 
      return 

     } 




     file.Read(read_file) 
     fileBytes := bytes.NewReader(read_file) 
     fileSize, err := buff.ReadFrom(fileBytes) 
     if err != nil { 
      log_errors(" error fileSize",err.Error(),w) 
      return 
     } 
     fileType := http.DetectContentType(read_file) 
     path := handler.Filename 
     params := &s3.PutObjectInput{ 
      Bucket: aws.String("bucket name"), 
      Key: aws.String(path), 
      Body: fileBytes, 

      ContentLength: aws.Int64(fileSize), 
      ContentType: aws.String(fileType), 
     } 

     resp, err := svc.PutObject(params) 
     if err != nil { 
      fmt.Printf("bad response: %s", err) 
      log_errors("error in putObject",err.Error(),w) 
      return 
     } 

     fmt.Println(w,"Done") 


    }() 
    wg.Wait() 

} 

Antwort

1

Improving speed? dies ist subjektiv; hängt von vielen Faktoren wie zB Server-Uplink, Client-Uplink usw.

Stattdessen werde ich meine Eingaben liefern, um Ihren Code-Schnipsel zu verbessern:

  • Beginnen wir mit sync.WaitGroup beginnen - ich sehe keinen Nutzen Gemäß Ihrem Code-Flow erstellen Sie einfach und warten auf die Ausführung von goroutine. Verwenden Sie stattdessen ohne WaitGroup. Tip: Verwenden Sie keine Funktion für Sake/Buzz; Verwenden Sie es bei Bedarf.
  • Erstellen Sie nicht mehrere bytes.Buffer und Reader, wenn Sie ohne es erreichen können. Für z.B. Dateigröße nach der Größenänderung erhalten, tun Sie einfach buf.Len().
  • Wenn Sie den AWS-Upload auslagern möchten, extrahieren Sie den Upload-Code-Teil in separate func und nennen Sie es als Goroutine.

Ich habe Ihr Code-Snippet aktualisiert (ich habe den Code nicht getestet, so wenden Sie sich bitte beheben/verbessern sie je nach Bedarf):

func UploadStreamImage(w http.ResponseWriter, r *http.Request) { 
    file, handler, err := r.FormFile("file") 
    if err != nil { 
     log_errors(" error on upload", err.Error(), w) 
     fmt.Println("Error Uploading Image") 
     return 
    } 
    defer file.Close() 

    // Suggestion: You can calculate the file size from bytes. 
    // instead getting it from form; since after resize image will change 
    imgSize, err := strconv.Atoi(r.FormValue("imgsize")) 
    if err != nil { 
     println("Error converting to integer") 
     log_errors("Error converting to integer", err.Error(), w) 
     return 
    } 

    img, err := imaging.Decode(file) 
    if err != nil { 
     print("Imaging Open error") 
     log_errors("Error decoding", err.Error(), w) 
     return 
    } 

    b := img.Bounds() 
    heightImg := b.Max.Y 
    widthImg := b.Max.X 

    // resize image 
    height := int(float64(heightImg) * .23) 
    width := int(float64(widthImg) * .23) 

    if imgSize < 401 { 
     height = int(float64(heightImg) * 1) 
     width = int(float64(widthImg) * 1) 

    } else if imgSize >= 401 && imgSize < 900 { 
     height = int(float64(heightImg) * .68) 
     width = int(float64(widthImg) * .68) 
     println("Middle Image") 
    } else if imgSize >= 900 && imgSize < 1300 { 
     height = int(float64(heightImg) * .45) 
     width = int(float64(widthImg) * .45) 
    } else if imgSize >= 1301 && imgSize < 1700 { 
     height = int(float64(heightImg) * .40) 
     width = int(float64(widthImg) * .40) 
    } 

    new_img := imaging.Resize(img, width, height, imaging.Lanczos) 
    // end resize 

    var buf bytes.Buffer 
    err = imaging.Encode(&buf, new_img, imaging.JPEG) 
    if err != nil { 
     log.Println(err) 
     log_errors(" error encoding file", err.Error(), w) 
     return 
    } 

    fileType := http.DetectContentType(buf.Bytes()) 
    fileSize := buf.Len() 
    path := handler.Filename 
    params := &s3.PutObjectInput{ 
     Bucket: aws.String("bucket name"), 
     Key: aws.String(path), 
     Body: bytes.NewReader(buf.Bytes()), 

     ContentLength: aws.Int64(fileSize), 
     ContentType: aws.String(fileType), 
    } 

    resp, err := svc.PutObject(params) 
    if err != nil { 
     fmt.Printf("bad response: %s", err) 
     log_errors("error in putObject", err.Error(), w) 
     return 
    } 

    fmt.Println("Done", resp) 
} 
+0

Vielen Dank für die Tipps sehr hilfreich Ihre Vorschläge umzusetzen . –

+0

@RomeTorres Gern geschehen. – jeevatkm

+0

Hey ich habe als Frage, dass Code oben auf einem Backend verwendet wird, aber angenommen, dass ich 1000 Benutzer hatte, die alle verschiedene Bilder hochladen, würde Goroutines mit wait.Sync Leistung verbessern? Für Golang bin ich noch ziemlich neu. –

Verwandte Themen