很久没有更新blog,一方面换了新工作,另一方面是懒。
很早就看见七牛,又拍云,新浪,阿里的图片处理了,当时觉得好厉害,没去研究里面的技术,后来@开发者头条 上有人实现了个简单的,基于openresty,openresty是我很早不知道的一个项目,可惜一直没入门lua. 这次新公司恰好有需要这个需求,本来是叫我这个运维找点开源的程序解决就ok,但是我这个“爱学习”的,怎么能放弃这个锻炼的机会。当然整 个项目我参考开源项目zimg
当然网上也有基于openresty(ngx_lua) 开源的项目,然而,我还是坚定要的造轮子。
最后一般公司除了特殊需求,还是建议使用七牛、又拍云提供的云存储及数据处理服务,解决图片的处理、存储、多节点访问速度的问题,这种方式优点是方案成熟,相应的有一定费用和开发工作省了。
# 介绍
# zimg
@招牌疯子开发。zimg的性能和扩展性不错,用c写的,大神,可惜版本也是没有大的更新,我这个项目架构就是参考他的设计。
# openresty
openresty 简直是高性能,异步非阻塞,6到不行,如果你只是觉得春哥(agentzh)只是打包工作,你还是too young, too native.
这东西一定要火,must be.
# graphicsmagick
GraphicsMagick是从 ImageMagick 分支出来,号称图像处理领域的瑞士军刀。 短小精悍的代码却提供了一个鲁棒、高效的工具和库集合,来处理图像的读取、写入和操作,支持超过88中图像格式,包括重要的DPX、GIF、JPEG、JPEG-2000、PNG、PDF、PNM和TIFF。 关键还提供了A simple Lua wrapper to graphicsmagick.
# ceph
一个 Linux PB 级分布式文件系统,当初我看到几个分布式的存储方案,tfs很久不更新了,sweeddfs简单一点,但是稳定性还是欠佳,并且还是有一些小问题。而ceph强大的强一制性,和自动修复能力,一下子就确实他了。
# 架构设计
# 访问流程
- 解析参数,并判断是否正确
- 从redis获取数据,否则从临时文件返回,并重新缓存到redis
- 若临时文件不存在,则使用原文件graphicsmagick生成新图片,保存并缓存。
- 若为ceph模式,则直接从ceph gateway获取,不会生成临时文件。
# 文件目录设计
这里借鉴 zimg 的方案,存储路径采用2级子目录的方案。由于 Linux 同目录下的子目录数最好不要超过2000个,再加上 MD5 的值本身就是32位十六进制数,zimg就采取了一种非常取巧的方式:根据 MD5 的前六位进行哈希,1-3位转换为十六进制数后除以4,范围正好落在1024以内,以这个数作为第一级子目录;4-6位同样处理,作为第二级子目录;二级子目录下是以 MD5 命名的文件夹,每个MD5文件夹内存储图片的原图和其他根据需要存储的版本.
├── 1024
│ └── 804
│ └── fffc929444a9fb7eb754217cfd7b0d58
│ ├── default
│ ├── w100_h100_g1_xnil_ynil_rnil_pnil_qnil_fnil
│ ├── w100_hnil_g1_xnil_ynil_rnil_pnil_qnil_fnil
│ ├── w100_hnil_gnil_xnil_ynil_rnil_pnil_qnil_fnil
│ └── wnil_hnil_gnil_xnil_ynil_rnil_pnil_qnil_fnil
├── 432
│ └── 471
│ └── 6c075eeaf073e39e280075450afb1cd0
│ └── default
└── 538
└── 429
└── 8686b4f53b5a392b90b9c0b35eaf9a11
└── default
当然ceph我采用对象存储(文件系统还不稳定,官方不推荐使用),就不存在目录结构了。
# 图片处理
通过url参数还生成对应的图像
url: ?w=300&h=300&g=1&x=0&y=0&r=45&q=85&f=jpeg
(? + 长 + 宽 + 灰白化 + x + y + 旋转角度 + 压缩比 + 转换格式)
w: 宽
h: 高
g: 黑白
r: 旋转
q: 压缩比
f: 格式
# 上传图片
因为路径信赖图片的 md5 生成,所以这里我用百度前端开源的image-upload模块,上传时带上图片的 md5 信息。
# 安装
# GraphicsMagick OpenResty
sudo apt-get install GraphicsMagick libgraphicsmagick1-dev
or
yum install GraphicsMagick GraphicsMagick-devel -y
# openresty
tar xvf ngx_openresty-VERSION.tar.gz
cd ngx_openresty-VERSION/
./configure
make
make install
# CMake-based LuaJIT + Luarocks
git clone https://github.com/torch/luajit-rocks.git
cd luajit-rocks
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/your/prefix -DWITH_LUAJIT21=ON
last
sudo luarocks install graphicsmagick
sudo luarocks install lua-resty-hmac
cd /usr/local/openresty/nginx/conf
mkdir conf.d
add "include conf.d/*.conf;" into nginx.conf
# last, in ngx-lua_images folder.
bash deploy.sh
# and add images folder, change it at config.lua if you need.
mkdir /home/files/images/
chown -R {nginx_user} /home/fiels/images
# 上传图片
http://localhost:8000/static/image-upload/
上传成功。
如果没有错误,就可以访问了。
http://localhost:8000/fffc929444a9fb7eb754217cfd7b0d58?w=500&h=500&g=1&x=0&y=0&r=45&q=75&f=jpeg
http://localhost:8000/get_info?md5=fffc929444a9fb7eb754217cfd7b0d58
# ceph
-
安装:略
-
configure:
- 修改./vendor/cephs3.lua的配置文件。
- 修改confi.json的ceph_mode为true。
- 删除nginx.conf的location /upload 段。
-
上传文件请使用ceph(s3 or swift) sdk上传文件和管理bucket.
# Benchmark
# 配置
渣配置
- CPU: Intel(R) Celeron(R) CPU G1620 @ 2.70GHz
- Memery: 2G
得益于 openresty 的高效(非阻塞,异步),结果是非常的出色。
clients/ | ngx-lua-images v1.0 | zimg v3.0.1 |
---|---|---|
10 | 5182.29 Requests/sec | 920.90 Requests/sec |
50 | 5077.43 Requests/sec | 957.33 Requests/sec |
100 | 5080.09 Requests/sec | 945.58 Requests/sec |