摘录:
最近接了应用开发组的一个需求,要求可以根据useragent重定向到指定的目录,还口口声声说要我们自己写nginx模块。刚开始很诧异,这不就是个$http_user_agent正则匹配加rewrite搞定的事吗,干嘛还要这么大动作?
开了个项目讨论会,原来useragent是一个多达3w条记录的库,不可能仅仅用正则表达式搞定。同时还要支持非运维人员对重定向规则进行定制,
所以选型里库用memcached做接口,nginx先请求memcached得到匹配规则,再根据返回重定向。貌似不是简单配置可以搞定的,唉,看来只能自己动手写代码了。
不过本人有个非常好的优点:懒,且不引以为耻。本着不重复造轮子的原则,我把wiki.nginx.org,nginx mailinglist翻了个遍。哈哈,果然是牛人无数,原来早就有个叫ngx_eval_module的模块可以完成此功能了:
eval的原理很简单,根据eval block中的配置发起一次子请求,并把子请求的返回结果重定义为一个变量,由主请求使用。
操作步骤如下:
1.编译
这个不用说,先把ngx_eval_module模块编到nginx中。(模块位置: )
./configure --prefix= --add-module=/path/to/nginx-eval-module
2. 配置
呵呵,当然这是亮点,再好使的狙击枪也得有个好射手(别!千万别打脸!):
location / {
#调用eval模块,将请求赋值为$memkey
eval $memkey {
# 利用if命令提取user_agent中的内容作为memecached的key,定义子请求为memcached请求
if ($http_user_agent ~ "([a-z]+).*$" ) {
set $memcached_key $1;
memcached_pass 127.0.0.1:11211;
break;
}
# 别忘了eval是个子请求,所以如果没有发给memcached,可就直接发本地了,死循环有木有!! 直接返回它
return 200;
}
# 如果memcached请求有返回,那就别说了,rewrite到其他location,干活去。。。,否则?那就该请求谁请求谁呗
if ($memkey) {
rewrite ^(.*)$ /detail/$memkey/$1 last;
}
}
# 具体重定向到的目录,当然可以是目录,代理, or any thing you like
location /detail {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8080;
}
此上就完成了UA重定向的需求。简单吧,嘿嘿,自己动手写模块可就不这么容易喽。
PS:这个模块只能支持一个子请求,国内大牛agentzhang因此写了个enhance版,可以支持多个子请求。But,
大牛并不推荐这个模块,因为传说已久的ifisevil问题,所以大牛直接推荐用他们已经用在生产上的lua模块(可是经过taobao验证哒!),什么
non-block啊,多线程啊,more
flexible啊之类的。不过本人这个需求很简单,就没折腾这个,毕竟是在nginx这么轻量的服务器上加一个全面的脚本解释器,还是慎重吧。不过以后
有时间研究研究倒是必须的。
阅读(2490) | 评论(0) | 转发(0) |