Golang编写简单图片服务器
图片服务器
最近的开发过程中,遇到一个问题,就是大量零碎图片的存储,最后我决定研究一个简单的图像服务器,以解决图像文件存储的性能问题。在此,写一篇博文记录我经历的思想过程和遇到的坑。
我们知道Linux存储文件不建议将大量文件存储到一个文件夹,这样做不仅容易大量消耗系统的iNode块,也很容易发生文件读写速度快速下降。
解决方案
通过分析需求,可得出一个方案,就是尽可能的让文件随机分布在不同的文件夹中,考虑到文件夹子文件数1000是个性能坎,可以给文件分配编号fileid,通过给fileid分区,就可以避免性能问题。
为了增加整个服务器的持续度,我决定使用uint64作为文件id,这样可以提供更大的计数区间,减少新建fileid的碰撞概率。
基本结构
结构很简单:
随机fileid发生器,fileid转文件路径(存储路径),JSON配置文件读取,上传、下载控制器
Golang使用JSON做配置文件
这里值得写的还是比较多的,
随机数生成
随机数生成部分我选择了seehuhn编写的mt19937库,项目地址:github.com/seehuhn/mt19937。
值得一提的是这个随机数库给的文档并不能用,简单地看了一下代码,发现正确用法应该是这样的:
mt:=mt19937.New()
mt.Seed(time.Now().UnixNano())
var buf = make([]byte, 8)
randuint64:=mt.Uint64()
随机fileid生成器代码
func MakeImageID()string{
mt:=mt19937.New()
mt.Seed(time.Now().UnixNano())
var buf = make([]byte, 8)
binary.BigEndian.PutUint64(buf, mt.Uint64())
return strings.ToUpper(hex.EncodeToString(buf))
}
我生成的fileid最后是这样形式的:6A778903AD673478,16位十六进制字符串,很适合存储在数据库中。
fileid转文件路径
使用了很Ugly的Sprintf方法