传统web应用图片不适合为手机用户服务,因为手机用户不需要大图,不想花太多的流量;
另一方面我们传统的图片保留下来的有xT,不可能在未知那些图片的情况下,把所有可能的图片
做一个转换。
所以需要为现有无线应用和传统图片搭一座桥,这桥的作用是:在手机用户访问的时候
实时进行图片转换。面临的问题是:现有的web server是一个进程服务一个用户,那它是忙不过来;
另一方面现有的转换图片的工具(
imagemagick)比较耗能,所以这次新架构主要客服这两方面
的问题。
简单架构图:
Nginx:进行分派作用,先暂时做URL Hash;
IMG-SERVER:把任务放进队列中,并肩负通知Nginx;
IMG-Worker:从队列中取出任务,进行处理,并将处理到的数据传送会Nginx相应的Root;
HttpSQS:任务队列,进行队列的存储。
简单架构概况:nginx->image-server->httpsqs->worker
nginx : 利用其url hash 尽量保持到后端image-server中的url唯一;
image-server: 接受用户的请求,维护着与用户的链接,与worker进行通信;
httpsqs:存储任务;
worker:进行图片处理或其它工作(例如:进行redis写入)。
为了一个进程能服务多个访问用户,使用一个异步的动作,这异步是利用jetty 异步servlet进行
(tomcat和resin 4.0以后 都支持了这个异步servlet -- servlet 3.0)
httpsqs:已队列形式进行存储任务。
简单架构图:
nginx把请求发到一个内嵌jetty的server,jetty server把相应任务存进队列中后继续服务其它用户。
worker从httpsqs中读取任务,从相应的地方把图片拿回来然后进行处理,处理完后通知回jetty server,
server中相应的服务线程会唤醒与用户的通信,如果处理中出现问题则向用户返回default.jpg。
代码流程图
从左往右看:用户->ImgServlet.java->TaskManaget.java->httpsqs;
worker(从httpsqs取出任务)->systemshell.java->AdminServlet.java->TaskManager.java->
ImgServlet.java->用户
上面为应用层的架构。
下面是对处理图片进行性能提升。
主要将三个功能进行合并以下为每个处理图片方法的性能数据:
convert 单线程 16.47分钟 6进程并发 30分钟 imageMagick load 22左右
python 脚本 单线程 15.38分钟 6进程并发 3.8分钟 python gil load 11左右
gm convert 单线程 13.46分钟 6进程并发 28分钟 g imagemagick load 22左右
econvert 单线程 10.5分钟 6进程并发 2.5分钟
exact-image load 7左右
为啥要将三个结合使用?
econvert 没按比例缩放功能
(
查看起源码,应该是有的,但估计因为性能上的问题,所以取了不少功能。
如代码中所示(exact-image-0.8.4/codecs 中头文件定义Codecs.hh --c++)
virtual bool scale (Image& image, double xscale, double yscale);
)
没有对png和gif处理的功能。但耗能低,速度快,质量能保证。
convert
能满足我们的所有需求,质量能达到要求,但耗能高,速度慢,这在实时应用或大批量转图的情况下会成为瓶颈。
python gil
能满足我们大部分功能需求,操作简单,速度可以,也是低耗,但质量不能满足(和具体算法有关)
虽然以前有接触过图片处理,但功力不够,力不从心,要再做也达不到convert和econvert的质量效果;
另一方面每个东西身上都有我们需要的东西,那不如把这三个结合起来使用,python gil(做计算为了
避免要另起进程),econvert做jpg处理,convert做gif(因为在我们网站中gif和png数量加起来才
是总量的2%,所有用户convert处理问题很不大);
阅读(1826) | 评论(0) | 转发(0) |