beego自动缓存静态文件导致占用20多G内存,且不会自动释放。
最近在查UDP收录的时候发现,beego写的web服务占用了20多G的内存。刚开始以为是内存泄漏了,后面通过一番搜索后发现,也有其他人遇到过这个问题。于是查看beego的源码,在 staticFile.go
中有个 openFile
方法。里面是把文件一次性读出来,然后放到一个 map
中缓存起来。
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, *serveContentReader, error) {
mapKey := acceptEncoding + ":" + filePath
mapLock.RLock()
mapFile := staticFileMap[mapKey]
mapLock.RUnlock()
if isOk(mapFile, fi) {
reader := &serveContentReader{Reader: bytes.NewReader(mapFile.data)}
return mapFile.encoding != "", mapFile.encoding, mapFile, reader, nil
}
mapLock.Lock()
defer mapLock.Unlock()
if mapFile = staticFileMap[mapKey]; !isOk(mapFile, fi) {
file, err := os.Open(filePath)
if err != nil {
return false, "", nil, nil, err
}
defer file.Close()
var bufferWriter bytes.Buffer
_, n, err := context.WriteFile(acceptEncoding, &bufferWriter, file)
if err != nil {
return false, "", nil, nil, err
}
mapFile = &serveContentHolder{data: bufferWriter.Bytes(), modTime: fi.ModTime(), size: int64(bufferWriter.Len()), encoding: n}
staticFileMap[mapKey] = mapFile
}
reader := &serveContentReader{Reader: bytes.NewReader(mapFile.data)}
return mapFile.encoding != "", mapFile.encoding, mapFile, reader, nil
}
于是我又去看了下 beego v2 的代码,发现静态文件实现和上面的代码差不多。
beego.SetStaticPath("/mnt", "/mnt")
千万不要使用以上方式设置及读取静态的大文件,不然服务会占用大量的内存。这种方式不适合当做大文件的静态服务,只能缓存基本的css和js文件,如果大量的图片的话也不建议这样使用。
如果这篇文章对你有所帮助,可以通过下边的“打赏”功能进行小额的打赏。
本网站部分内容来源于互联网,如有侵犯版权请来信告知,我们将立即处理。