我有一些图像,我使用官方的亚马逊s3包上传到我的s3帐户。我的图像通常大约250 - 350 KB这么小的图像,但它们需要大约8或9秒上传,这似乎过多任何提高速度的建议都会很棒。这是我的代码,如果我将调整大小的图像代码关闭,它仍然需要8或9秒钟。
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()
}
答案 0 :(得分:2)
Improving speed?
这是主观的;取决于许多因素,如服务器上行链路,客户端上行链路等。
相反,我会提供改进您的代码段的输入:
sync.WaitGroup
开始 - 根据您的代码流程,我没有看到任何好处,您只需创建并等待goroutine完成。而不使用WaitGroup。 Tip:
不要将功能用于清酒/嗡嗡声;在需要时使用它。bytes.Buffer
和Reader
。对于例如调整大小后获取fileSize,只需执行buf.Len()
。func
中,并将其称为goroutine。我已更新您的代码段(我尚未测试您的代码,因此请根据需要修复/改进):
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)
}