免责声明:我不确定标题是否是我的实际问题,但这是唯一有意义的解释。
场景
我正在将大型视频上传到我的Golang服务器。我有一个8GB的文件,在本地大约需要15分钟,并且运行良好。但是,在我的登台服务器(Google Cloud)上,此文件需要花一个多小时才能上传,这就是问题所在。
问题
我的客户端正在等待文件完成上传,以调用另一个API端点,但是只有在登台服务器上它才会失败。这样看来,当我的服务器希望编写响应时,连接将不允许它,因为客户端显示了502
错误和CORS错误,我知道这是Chrome所说的“我们不愿意”不知道,请检查您的服务器”。
代码
在我的SrcHandler
里面是这样:
defer func(begin time.Time) {
pr, pw := io.Pipe()
defer pw.Close()
if err := r.ParseMultipartForm(32 << 20); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
fmt.Printf("%v\n", err)
return
}
srcFile, handler, err := r.FormFile("video")
if err != nil {
http.Error(w, "INVALID_FILE", http.StatusBadRequest)
return
}
defer srcFile.Close()
// Copy uploaded file to *PipeWriter
go func() {
defer srcFile.Close()
defer pw.Close()
io.Copy(pw, srcFile)
}()
// Prep fileName
var srcFileName = strings.Replace(handler.Filename, " ", "_", -1)
var extension = filepath.Ext(srcFileName)
srcFileName = srcFileName[0 : len(srcFileName)-len(extension)]
// Create temp file to write too
f, err := ioutil.TempFile("./tmp/pending", srcFileName+"_")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Copy *PipeReader to temp file
io.Copy(f, pr)
contentType, err := getFileContentType("./" + f.Name())
if err != nil {
fmt.Printf("Content Type Error: %v\n", err)
return
}
fmt.Printf("ContentType = %v\n ", contentType)
if contentType != "video/x-flv" && contentType != "video/mp4" &&
contentType != "video/quicktime" && contentType != "video/x-msvideo" &&
contentType != "video/x-ms-wmv" && contentType != "video/webm" {
http.Error(w, "INVALID_FILE_TYPE", http.StatusBadRequest)
os.Remove(f.Name())
return
}
fmt.Printf("Upload path -> %v\n", f.Name())
upload := UploaderResponse{srcFileName, "./" + f.Name()}
resp, err := json.Marshal(upload)
if err != nil {
fmt.Printf("Error using Marshal %v\n", err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
status, err2 := w.Write(resp)
if err2 != nil {
fmt.Printf("Error when writing response to app %v\n", err2)
} else {
fmt.Printf("Status from uploading: %v\n", status)
}
_ = u.logger.Log("upload.Handler Duration ", time.Since(begin))
}(time.Now())
代码下降到最后一行,u.logger.Log()
实际上显示输出。因此视频已正确上传...仅响应客户端失败。有人有想法吗?
免责声明2:我刚刚发现w.Write
返回错误,因此我正在等待文件完成上传,看看是否记录了错误。将以更新进行响应。
我上传了一个新文件,并且w.Write()
调用成功,返回了91
整数。我不确定现在可能是什么问题。可能是我不知道的地方超时了。仅供参考,我的服务器读写超时均为6小时。
答案 0 :(得分:0)
我当时在球场上提到超时,但事实证明此问题与代码无关。我偶然发现了另一个具有相同问题的SO post,但在AWS上。问题是负载均衡器超时。我使用了Google Cloud's docs中的说明,将超时从默认的30秒增加到几个小时。具体来说,超时设置是对服务器等待发送响应到客户端的等待时间的计数。