为什么80%的码农都做不了架构师?>>>   

这几个月里,我们逐步把Lua集成到Mixlr的前端Nginx配置中。 Lua是一个可以嵌入到Nginx配置文件中的动态脚本语言,从而可以在Nginx请求处理的任何阶段执行各种Lua代码。刚开始我们只是用Lua 把请求路由到后端服务器,但是它对我们架构的作用超出了我们的预期。下面就讲讲我们所做的工作。 强制搜索引擎只索引mixlr.com Google把子域名当作完全独立的网站,我们不希望爬虫抓取子域名的页面,降低我们的Page rank。

location / {header_filter_by_lua 'if ngx.var.query_string and ngx.re.match( ngx.var.query_string, "^([0-9]{10})$" ) thenngx.header["Expires"] = ngx.http_time( ngx.time() + 31536000 ); ngx.header["Cache-Control"] = "max-age=31536000";end';

如果对robots.txt的请求不是mixlr.com域名的话,则内部重写到robots_diallow.txt,虽然标准的重写指令也可以实现这个需求,但是 Lua的实现更容易理解和维护。 根据程序逻辑设置响应头 Lua提供了比Nginx默认配置规则更加灵活的设置方式。 在下面的例子中,我们要保证正确设置响应头,这样浏览器如果发送了指定请求头后,就可以 无限期缓存静态文件,是的用户只需下载一次即可。 这个重写规则使得任何静态文件,如果请求参数中包含时间戳值,那么就设置相应的Expires和Cache-Control响应头。

location / {header_filter_by_lua 'if ngx.var.query_string and ngx.re.match( ngx.var.query_string, "^([0-9]{10})$" ) thenngx.header["Expires"] = ngx.http_time( ngx.time() + 31536000 ); ngx.header["Cache-Control"] = "max-age=31536000";end';try_files $uri @dynamic;}

删除jQuery JSONP请求的时间戳参数 很多外部客户端请求JSONP接口时,都会包含一个时间戳类似的参数,从而导致Nginx proxy缓存无法命中(因为无法忽略指定的HTTP参数)。下面的 规则删除了时间戳参数,使得Nginx可以缓存upstream server的响应内容,减轻后端服务器的负载。

location / {rewrite_by_lua 'if ngx.var.args ~= nil then-- /some_request?_=1346491660 becomes /some_requestlocal fixed_args, count = ngx.re.sub( ngx.var.args, "&?_=[0-9]+", "" );if count > 0 thenreturn ngx.exec(ngx.var.uri, fixed_args);endend';}

把后端的慢请求日志记录到Nginx的错误日志 如果后端请求响应很慢,可以把它记录到Nginx的错误日志,以备后续追查。

location / {log_by_lua 'if tonumber(ngx.var.upstream_response_time) >= 1 thenngx.log(ngx.WARN, "[SLOW] Ngx upstream response time: " .. ngx.var.upstream_response_time .. "s from " .. ngx.var.upstream_addr);end';}

基于Redis的实时IP封禁 某些情况下,需要阻止流氓爬虫的抓取,这可以通过专门的封禁设备去做,但是通过Lua,也可以实现简单版本的封禁。

lua_shared_dict banned_ips 1m; location / {access_by_lua 'local banned_ips = ngx.shared.banned_ips;local updated_at = banned_ips:get("updated_at");-- only update banned_ips from Redis once every ten seconds:if updated_at == nil or updated_at < ( ngx.now() - 10 ) thenlocal redis = require "resty.redis";local red = redis:new();red:set_timeout(200);local ok, err = red:connect("your-redis-hostname", 6379);if not ok thenngx.log(ngx.WARN, "Redis connection error retrieving banned_ips: " .. err);elselocal updated_banned_ips, err = red:smembers("banned_ips");if err thenngx.log(ngx.WARN, "Redis read error retrieving banned_ips: " .. err);else-- replace the locally stored banned_ips with the updated values:banned_ips:flush_all();for index, banned_ip in ipairs(updated_banned_ips) dobanned_ips:set(banned_ip, true);endbanned_ips:set("updated_at", ngx.now());endendendif banned_ips:get(ngx.var.remote_addr) thenngx.log(ngx.WARN, "Banned IP detected and refused access: " .. ngx.var.remote_addr);return ngx.exit(ngx.HTTP_FORBIDDEN);end';}

现在就可以阻止特定IP的访问:

ruby> $redis.sadd("banned_ips", "200.1.35.4")

Nginx进程每隔10秒从Redis获取一次最新的禁止IP名单。需要注意的是,如果架构中使用了Haproxy这样类似的负载均衡服务器时, 需要把$remote_addr设置为正确的远端IP地址。 这个方法还可以用于HTTP User-Agent字段的检查,要求满足指定条件。 使用Nginx输出CSRF(form_authenticity_token) Mixlr大量使用页面缓存,由此引入的一个问题是如何给每个页面输出会话级别的CSRF token。我们通过Nginx的子请求,从upstream web server 获取token,然后利用Nginx的SSI(server-side include)功能输出到页面中。这样既解决了CSRF攻击问题,也保证了cache能被正常利用。

location /csrf_token_endpoint {internal;include /opt/nginx/conf/proxy.conf;proxy_pass "http://upstream";}location @dynamic {ssi on;set $csrf_token '';rewrite_by_lua '-- Using a subrequest, we our upstream servers for the CSRF token for this session:local csrf_capture = ngx.location.capture("/csrf_token_endpoint");if csrf_capture.status == 200 thenngx.var.csrf_token = csrf_capture.body;-- if this is a new session, ensure it sticks by passing through the new session_id-- to both the subsequent upstream request, and the response:if not ngx.var.cookie_session thenlocal match = ngx.re.match(csrf_capture.header["Set-Cookie"], "session=([a-zA-Z0-9_+=/+]+);");if match thenngx.req.set_header("Cookie", "session=" .. match[1]);ngx.header["Set-Cookie"] = csrf_capture.header["Set-Cookie"]; endendelsengx.log(ngx.WARN, "No CSRF token returned from upstream, ignoring.");end';try_files /maintenance.html /rails_cache$uri @thin;}

CSRF token生成 app/metal/csrf_token_endpoint.rb:

class CsrfTokenEndpointdef self.call(env)if env["PATH_INFO"] =~ /^\/csrf_token_endpoint/session = env["rack.session"] || {}token = session[:_csrf_token]if token.nil?token = SecureRandom.base64(32)session[:_csrf_token] = tokenend[ 200, { "Content-Type" => "text/plain" }, [ token ] ]else      [404, {"Content-Type" => "text/html"}, ["Not Found"]]endendend

我们的模版文件示例: <meta name="csrf-param" value="authenticity_token"/> <meta name="csrf-token" value="<!--# echo var="csrf_token" default="" encoding="none" -->"/> Again you could make use of lua_shared_dict to store in memory the CSRF token for a particular session. This minimises the number of trips made to /csrf_token_endpoint. 原文链接:http://devblog.mixlr.com/2012/09/01/nginx-lua/

转载于:https://my.oschina.net/766/blog/210843

Nginx 与 Lua相关推荐

  1. 实战:Nginx集成Lua脚本并调用memcached

    之前在阿里云的centos系统上已经安装过nginx,但是没有安装lua所需的模块,因此重新编译nginx来扩展lua模块. ngx_lua_module 是一个nginx http模块,它把 lua ...

  2. Nginx与Lua开发

    1.Lua及基础语法 Nginx与Lua环境 场景:用Nginx结合Lua实现代码的灰度发布 1.Lua 是一个简洁.轻量.可扩展的脚本语言 2.Nginx+Lua优势 充分的结合Nginx的并发处理 ...

  3. 11: Nginx安装lua支持

    1.1 Nginx 使用lua脚本 注:需要LuaJIT-2.0.4.tar.gz,ngx_devel_kit,lua-nginx-module 1.Nginx安装lua支持 wget -c http ...

  4. CentOS7下Nginx 安装 Lua 支持

    Nginx 支持 Lua 需要安装 lua-nginx-module 模块,一般常用有 2 种方法: 1.编译 Nginx 的时候带上 lua-nginx-module 模块一起编译 2.使用 Ope ...

  5. centos上搭建nginx视频点播服务器(nginx+vod+lua http发送鉴权消息)

    需求背景: 想着搭建一个视频点播服务器,最后选择了nginx+vod的方案,用lua脚本写拉流鉴权,但是环境搭建过程中又发现nginx++vod+lua的环境并不是很容易搭建,是nginx+lua的环 ...

  6. 使用Nginx和Lua进行图片webp压缩处理

    一般商品主图大小为800800(淘宝)或者750750(京东),即便以72*72的分辨率去做图,图片的大小也有几百k,对于移动端而已,图片过大,加载过慢,于是研究了下用Nginx和Lua进行图片web ...

  7. 分布式接口幂等性、分布式限流:Guava 、nginx和lua限流

    点击关注公众号,实用技术文章及时了解 一.接口幂等性 接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用.举个最简单的例子,那就是支付,用户购买商品 ...

  8. 分布式接口幂等性、分布式限流(Guava 、nginx和lua限流)

    一.接口幂等性 接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用.举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时 ...

  9. Nginx利用lua剪辑FastDFS图片

    Nginx利用lua剪辑FastDFS中的图片 我们经常用FastDFS来做图片服务器,通过nginx来上传或者获取图片.本文要实现的功能是,当客户端要获取不同尺寸的图片是,lua根据url中的尺寸大 ...

  10. Nginx安装Lua

    Nginx安装Lua 1.安装Lua(两个二选一) yum install readline-devel (CentOS) sudo apt-get install libreadline-dev ( ...

最新文章

  1. java 重试_Java重试机制修改
  2. [JS]string.substr(start,length)str.slice(begin, end)
  3. 【LeetCode】200. 岛屿的个数
  4. spring aop 注释_使用Spring AOP,自定义注释和反射为您的应用程序审核基础结构
  5. Physically Based Specular for Artists
  6. 15_传智播客iOS视频教程_OC语言完全兼容C语言
  7. nginx 分别对各个域名跳转
  8. BZOJ3091 城市旅行
  9. Android 高德地图搜索功能相关
  10. Minio纠删码与存储级别
  11. 通过CSS美化Web页面
  12. python输入数字变时间_转变大写日期为数字格式
  13. 打游戏经常有人喷,刷个B站还是有?Python实现在网站上自动评论!键盘侠都喷不赢你!
  14. 开放PLM——Aras Innovator编程学习(一)简介
  15. php pear pecl 区别,pecl 简单介绍
  16. 隐藏应用图标的多种方式
  17. 112358序列c语言,112358(112358的规律是什么)
  18. 【运筹学】对偶理论总结 ( 对称性质 | 弱对偶定理 | 最优性定理 | 强对偶性 | 互补松弛定理 ) ★★★
  19. SWFUpload使用
  20. allegro标注尺寸设置_Allegro中尺寸标注文字的设置

热门文章

  1. 中小型企业OA的需求和预算之间有什么关联?
  2. Matlab实验之画茶壶
  3. javascript问题汇总
  4. Mabot机器人趣味视频教程-扫地机器人
  5. OSChina 周日乱弹 —— 一看就知道你不是什么正经猫
  6. Vue01-创建Vue实例以及各选项含义
  7. Bootstrap栅格系统 显示当前屏幕大小和种类
  8. Spring WebFlux框架 - WebFlux 配置
  9. datawhale组队学习 Task02 - 艺术画笔见乾坤
  10. springboot 模块引用_SpringBoot项目之间相互引用