博客再次改版了,这次在细节方面做了一些调整。
beego内存占用不释放问题
时间:2020-12-18 15:27:18 +0800 CST 浏览:163

摘要

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



如果这篇文章对你有所帮助,可以通过下边的“打赏”功能进行小额的打赏。

本网站部分内容来源于互联网,如有侵犯版权请来信告知,我们将立即处理。


来说两句吧