目前遇到的一个网站改造项目,由于历史原因,全站的图片都在放在几个目录下存放,每个目录图片文件数量能达到数十万。

网站流量增加后,明显IO上造成了巨大瓶颈,唯一的办法就是将图片移走,换一个专用的图片域名,然后把图片按Hash值分目录存放,控制每个目录的图片数量在一个合理范围。

不过,这样改造的工程量浩大。

且不说要更改上传图片的程序,图片更换目录后,所有的图片链接地址变化了,意味着有大量的前端页面图片会出错。

这样的改造工期过长,涉及到的开发量过大。

好,现在squid就派上用上了。

目标其实很简单:squid的cache目录管理是hash目录存储的,只要想一个办法把现在的图片文件嫁接到squid的cache里就搞定了。

第一步:建立一个图片专用虚拟主机,映射网站的图片目录。

这台机器的IP假设为 133.33.33.31

比如网站的域名是 www.dayuer.com,用同样的目录新建一个 image.dayuer.com;

注意,在dns里不要把image.dayuer.com指到这台主机,这个主机仅仅是squid访问的而已。

这样,访问 www.dayuer.com/images/xxx.jpg等同于 image.dayuer.com/images/xxx.jpg

第二步:在另外一台服务器装squid,配置成透明反向代理

这台机器的IP假设为 122.22.22.221

具体的步骤google多的是。这台squid是用来代理image.dayuer.com的;

squid的hosts里解析 image.dayuer.com

在dayuer.com的dns服务器里设子域名 image.dayuer.com = 122.22.22.221

如果配置成功,现在访问 image.dayuer.com/images/xxx.jpg就能看到图片了

第三步:前面的工作做好以后,就要把对www.dayuer.com的图片访问转移到image.dayuer.com的访问

OK,现在是关键:

www.dayuer.com的主机配置文件里,增加一个rewrite规则:

Redirect /images http://image.dayuer.com/images

这样,访问www.dayuer.com/images/xxx.jpg的时候,apache会发出一个302转向,去请求 image.dayuer.com/images/xxx.jpg,这个过程在浏览器里看不出来,用户完全不会有感觉。

好了,到现在为止,图片目录就被顺利的嫁接到squid的cache里了。

看起来好像没什么变化

分析一下访问一个图片的请求情况

访问http://www.dayuer.com/images/xxx.jpg

请求到达apache后,根据rewrite规则,会被转到

http://image.dayuer.com/images/xxx.jpg

这时,请求到达squid了,squid检查cache,发现没有缓存,那么去请求原始文件

squid根据hosts的设置,知道image.dayuer.com的真实ip是133.33.33.31,然后把请求发过去

这时,image的虚拟主机接受到请求,返回图片给squid,squid再把图片返回给浏览器

然后浏览器里就出现图片了。

说到这,估计有人不明白,干嘛这么绕一圈,累死人了。

的确是绕了一圈,不过这么一来,原来的程序不用修改了,页面也不用改了,文件目录也不用挪走了,以前的一切该怎样还怎样。

但是,用户访问image的流量,确确实实被转移到了squid,不会再读取本地的图片目录,IO瓶颈没了。

大量的文件按Hash目录结构存放到了squid的cache目录里

一个快被流量压垮的网站,就这么分解了流量,重新又活了,这一切,一句代码都没有改过。


3 条评论

  1. 的确是好办法!

  2. 302 redirect 会造成浏览器多次请求, 肯定会慢一点,算是一个后遗症吧

  3. 大量的302肯定要慢些!记得squid好像本身带一个redirect功能的