使用Nginx+Lua对某新闻站进行架构优化

缘由:

某IIS新闻站点(地区门户),原先部署了nginx做反向代理;squid缓存;以及1IIS源+2台文件存储服务器

预期要改造为cms站点,仅有静态文件;cms后台由其它server运行

 

方案一

使用2台文件存储服务器安装nginx,通过rsync做文件同步

上线后发现以下几个问题:

1.首页加载需要8秒以上

2.双机文件同步耗时过长,每次同步都在5min以上

3.磁盘IO过高

经过详细检查,存在以下问题:

1.新闻编辑人员经常在页面中插入多张上百K图片,导致页面过大,特别是首页经常达到2~3M

2.旧文件数据过多过大,350G文件总量,但文件数上千万

好吧,其实海量小文件的解决方案才是需要说明的重点,于是就有了……

sa:上缓存吧,速度快,效果好

dev:不行,上缓存我还要写程序purge,代码改动很麻烦

sa:…

sa:那旧文件删除,0x年的新闻页面现在还有谁看

dev:不行,业务领导那边不同意

sa:怎么什么都不行,那你想个法

dev:我们做冷热数据分离吧

sa:说的容易,怎么实施,首先怎么判断数据冷热?

dev:新的就是热的,旧的就是冷的

sa:废话- -,怎么判断...

dev:像http://news.qq.com/a/20140514/007123.htm,url中会带有时间戳

sa:那你这个时间肯定是动态的,如果说最近3个月为热数据,1月份的热数据就是去年11月至今;5月份的热数据就是3月份至今

dev:对呀,而且时间戳还有好多种,有yyyymmdd/hh/的,也有yyyy/mm/dd,也有yymm/dd的

sa:卧槽,格式又多,判断条件也要随时间变化,哪个设备哪个服务都做不到啊

sa:==我想到一个好像可以,nginx+lua

 

方案二

其实从往常的应用经验看,【nginx+不多的静态文件】即使是稍微老一点的服务器,服务性能也是非常好的;而本新闻站的最大拖累就在LOSF(海量小文件)

这些几百G,上千万的小文件,其实多数是2006年-2012年的历史文件,作为一个新闻站点来讲,这种历史文件的访问量是非常小,几乎为0的

所以我们决定,上线2台新设备,承担新文件的访问;而目前的设备,作为文件存储及承担旧文件访问的用途

为什么选择lua?

lua是目前所遇到过的速度最快的嵌入式脚本语言;一个完整的lua解释器不过200K;

在下的脚本肯定会有多if等判断,引入lua在web server上做7层代理,不至于对server造成过大负载

如果将lua应用到我们现在的架构中?当然是先学习,后部署

首先,学习lua

lua官方手册是最好的学习地址:http://www.codingnow.com/2000/download/lua_manual.html

其次,了解nginx的lua module

http://wiki.nginx.org/HttpLuaModule

最后,可以参考其它同学的应用经验

 

那么就开始lua安装

   1:  tar zxvf LuaJIT-2.0.0.tar.gz
   2:  cd LuaJIT-2.0.0
   3:  make && make install

 

nginx安装,加入lua module即可

   1:  ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" --add-module=ngx_module/echo-nginx-module-master --add-module=ngx_module/lua-nginx-module-0.7.14rc2/
   2:  make && make install

 

编辑nginx.conf,主要的地方就在于

1.引入lua脚本

2.制定访问的location

 server {
    ... 
    # 引入lua file
    location / {
        content_by_lua_file 'conf/proxy_pass.lua';
    }
    # 建两个location,@local为访问本地,@proxy_pass为访问后端
    location @local {
        #echo "@local";
        root  /www/webadmin;
        index index.shtml index.html;
    }
    location @proxy_pass {
        #echo "@proxy_pass";
        proxy_pass http://backend;
        include /usr/local/nginx/conf/proxy.conf;
    }
    ...
 }

 

编辑proxy_pass.lua文件,架构上线时间为2013年5月,lua脚本最后一次更新为2013年8月

只po干货,判断部分就不说了,每个人业务情况不一样~

-- Version 0.9999 -- 2013/08/01 potaski@qq.com
ngx.req.read_body()
-- 获取url
url = string.gsub(ngx.unescape_uri(ngx.var.request_uri),'\\%','')
-- 上面获取url的方式,如果url为"news.qq.com/"这样的话,取得的值为nil,我被坑了一回~
...
-- 当判断结束后,可以通过ngx.exec('@location_name'),进行跳转处理
if url_date == jgp_time_1 or url_date == jpg_time_2  then
    ngx.exec('@local')
else
    ngx.exec('@proxy_pass')
end

 

目前此架构已稳定运行一年,现在运行nginx+lua的设备,为2008年的单颗E2180,内存4G服务器,单台高峰时连接1K+,CPU损耗峰值在50%

nginx+lua设备只存放最近3个月的文件数据,并定期删除;其余数据全部由后端存储;磁盘压力大大减小

效果不错,所有人都很满意

posted @ 2014-05-14 16:58  zw1027  阅读(987)  评论(0编辑  收藏  举报