beego自动缓存静态文件导致占用20多G内存,且不会自动释放。

问题所在

staticFile.goopenFilemap
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文件,如果大量的图片的话也不建议这样使用。