导读:nginx是一个高性能的反向代理服务器,lua是一个小巧的脚本语言,这两个的巧妙结合会擦出怎样的火花呢。

关键词:nginx,lua,nginx+lua

前言

nginx,lua,nginx+lua,这三个名词不知道大家熟悉多少。为了后面内容的展示,我简单的介绍一下它们,想深入了解的网上资料很多,在这就不啰嗦了。nginx是一个高性能的反向代理服务器,一般会处在网站的最前端(有可能前面还会加一层slb,在这暂时忽略),用来做后端web服务的代理;lua是一个小巧的脚本语言,其设计的目的就是嵌入应用程序中,为其提供一些扩展和增强,比如redis,nginx等等;nginx+lua顾名思义就是nginx和lua的结合体,这两者之间沟通的桥梁是nginx_lua_module,它是nginx的一个模块,有了它nginx和lua才能互通,笔者在最近几年的工作中恰好有这方面的开发经验,所以想把这些真实的使用场景分享出来供大家做参考,具体的api doc还请大家参考官方资料。

案例1-入口层流量的灰度识别

何谓入口层流量的灰度识别呢,简单来说就是A用户的请求打到线上环境,B用户的请求打到灰度环境,目的就是做新功能的验证,实现逻辑很简单,大体流程如下:

1.测试同学在灰度控制台配置灰度规则,规则里会约束哪些url下哪些商户的请求进入灰度环境;

2.灰度控制台推送规则给入口层nginx,nginx会将规则存储到本地内存中,借助ngx.shared.DICT

3.请求进入的时候(通过rewrite_by_lua_file触发)获取本地内存中的规则进行比对,如何命中规则就将请求转发到灰度环境,对nginx来说就是切换不同的upstream,比如线上是prod_serverA,灰度是gray_serverA;

代码片段如下:

upstream  gray_serverA {
server 192.68.1.1:8080;
} upstream prod_serverA {
server 192.68.1.2:8080;
} server {
listen 80;
server_name graytest.demo.com;
charset utf-8; location ~ \.do$ {
set $backend 'prod_serverA'; #默认的upstream为线上服务
rewrite_by_lua_file "conf/lua-gray/rewriter.lua"; # rewrite_by_lua_file 可以简单的理解为一个过滤器,nginx在rewrite阶段会执行你指定的脚本文件,
           #在这个文件中我们会判断请求是否为灰度请求如果是灰度请求就将backend改为gray_serverA
proxy_pass http://$backend;
}
}

  

案例2-入口层记录错误日志

之前有同学反馈说springmvc偶尔会报415错误,这个错误的一个常见原因是传递的Content-Type头不对,比如后端需要application/json,但是前端传递了application/x-www-form-urlencoded,那就会报这个错。但是跟前端确认了传递的头是没有问题的,有人猜测可能是头信息有特殊字符,导致后端web 容器(tomcat、resin)解析头出现了问题,既然这样把所有请求头打出来一看究竟,于是lua再一次出场,这次主要用来输出请求头到日志文件中,主要用到了log_by_lua_block这个指令,代码片段如下:

location  ~ \.do$ {
proxy_pass http://$backend;
log_by_lua_block {
      //判断下如果http 响应状态码为415就输出请求头到文件中
if tonumber(ngx.var.status) == 415 then
ngx.log(ngx.ERR,"upstream reponse status is 415,please notice it,here are request headers:")
local h, err = ngx.req.get_headers(100,true) if err == "truncated" then
ngx.log(ngx.ERR,"request headers beyond 100,will not return")
else
local cjson = require("cjson")
ngx.log(ngx.ERR,cjson.encode(h))
end
end
}
}

想详细了解这个案例的,请移步到我的另一篇博客(https://www.cnblogs.com/chopper-poet/p/11625144.html)。

案例3-将nginx信息注册到监控平台

需求很简单,当nginx启动的时候将自身信息上报到redis中,上报内容包扣自身的ip,代理的域名信息等,有个监控平台会定期从redis读取这些信息做展示,方便运维干活,流程很简单就是定时读取自身ip和代理的域名信息写到redis中,为什么要定时呢,这里还起到一种心跳的效果,当长时间没有上报时可能是nginx出问题了,主要用到的指令如下:

1.init_worker_by_lua_file "conf/ua-grayngxReloadListener.lua",当nginx启动或者reload的时候会执行指定的文件;

2.ngx.worker.id() 这个方法会返回nginx worker进程的编号,从0开始,如果nginx有4个worker,那取值范围为0-3,这个主要是为了防止并发上报,因为第一步里面提到的init_worker_by_lua_file,如果有几个worker就会触发几次,所以为了只上报一次,会判断下返回值是否为0,也就是只让第一个worker执行;

3.ngx.timer.every 用来执行定时任务;

代码片段如下:

local workerId = ngx.worker.id()

if(workerId == 0) then
ngx.log(ngx.INFO,'workerId is 0 will startup task') local ok, err = ngx.timer.every(4,function()
#1. get local ip and domins
#2. write to redis
end) else
ngx.log(ngx.INFO,'workerId is not 0 ,just ignore it')
end

 

案例4-将入口层流量同时转发到多个后端服务

类似于消息队列的发布订阅一样,在nginx这一层可以将一个请求同时发到多个地址,代码片段如下:

location  ~ /capture_test$ {
content_by_lua_block {
ngx.req.read_body() res1, res3 = ngx.location.capture_multi{
{ "/capture_test1",{ method = ngx.HTTP_POST, always_forward_body=true}},
{ "/capture_test2",{ method = ngx.HTTP_POST, always_forward_body=true}},
} ngx.say(res3.body)
ngx.exit(res3.status)
}

总结

上面列举了nginx+lua在我司使用的四个案例,真实场景要复杂很多,为了方便大家理解,特意将案例做了简化。如果觉得有用,请点个推荐。

参考资料

https://github.com/openresty/lua-nginx-module

nginx+lua在我司的实践的更多相关文章

  1. 基于nginx+lua+redis高性能api应用实践

    基于nginx+lua+redis高性能api应用实践 前言 比较传统的服务端程序(PHP.FAST CGI等),大多都是通过每产生一个请求,都会有一个进程与之相对应,请求处理完毕后相关进程自动释放. ...

  2. 用Nginx+Lua(OpenResty)开发高性能Web应用

    在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛.Nginx的高性能是大家公认的,而Nginx开 ...

  3. Nginx+Lua(OpenResty)开发高性能Web应用

    使用Nginx+Lua(OpenResty)开发高性能Web应用 博客分类: 跟我学Nginx+Lua开发 架构 ngx_luaopenresty 在互联网公司,Nginx可以说是标配组件,但是主要场 ...

  4. 使用Nginx+Lua(OpenResty)开发高性能Web应用

    摘自(http://jinnianshilongnian.iteye.com/blog/2280928) 在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等 ...

  5. 搭建OpenResty(Nginx+Lua)

    这篇文章是一个多月前写的,当时之所以搭建这个是为了最大程度上发挥Nginx的高并发效率(主要是结合lua脚本),参考的话,主要参考张开涛先生写的跟开涛学Nginx+lua系列文章,地址为:https: ...

  6. 单机闭环 使用Nginx+Lua开发高性能Web应用

    [西域骆驼D1532101213]西域骆驼(VANCAMEL)D1532101213 休闲套脚鞋 卡其43[行情 报价 价格 评测]-京东 http://item.jd.com/1856564.htm ...

  7. 跟我学OpenResty(Nginx+Lua)开发目录贴 (转)

    使用Nginx+Lua开发近一年的时间,学习和实践了一些Nginx+Lua开发的架构,为了让更多人使用Nginx+Lua架构开发,利用春节期间总结了一份基本的学习教程,希望对大家有用.也欢迎谈探讨学习 ...

  8. Nginx基础 - Nginx+Lua实现灰度发布与WAF

    1.Nginx加载Lua环境默认情况下Nginx不支持Lua模块, 需要安装LuaJIT解释器, 并且需要重新编译Nginx, 建议使用openrestry 1)环境准备 [root@localhos ...

  9. 使用Nginx+Lua代理Hadoop HA

    一.Hadoop HA的Web页面访问 Hadoop开启HA后,会同时存在两个Master组件提供服务,其中正在使用的组件称为Active,另一个作为备份称为Standby,例如HDFS的NameNo ...

随机推荐

  1. CAP 3.0 版本发布通告

    前言 大家好,我们很高兴宣布 CAP 发布了 3.0 版本正式版. 自从上次 CAP 2.6 版本发布 以来,已经过去了几个月的时间,关注的朋友可能知道,在这几个月的时间里,也发布了几个预览版的 3. ...

  2. 14.python案例:爬取电影天堂中所有电视剧信息

    1.python案例:爬取电影天堂中所有电视剧信息 #!/usr/bin/env python3 # -*- coding: UTF-8 -*- '''======================== ...

  3. 从头学pytorch(十六):VGG NET

    VGG AlexNet在Lenet的基础上增加了几个卷积层,改变了卷积核大小,每一层输出通道数目等,并且取得了很好的效果.但是并没有提出一个简单有效的思路. VGG做到了这一点,提出了可以通过重复使⽤ ...

  4. oracle的一些简单语法

    1.创建主键自增: --创建序列 create sequence seq_tb_user minvalue nomaxvalue start with increment by nocycle --一 ...

  5. kaggle预测房价的代码步骤

    # -*- coding: utf-8 -*- """ Created on Sat Oct 20 14:03:05 2018 @author: 12958 " ...

  6. java 储存机制

    1.栈 statck 局部变量名称 2.堆 heap 带new的 3.方法区 method area .class

  7. chrome清除缓存快捷键

    CTRL+SHIFT+DEL:直接进入“清除浏览数据”页面,包括清除浏览历史记录.清空缓存.删除Cookie等. 进入开发者模式settings

  8. python接口自动化中,注册接口随机生成手机号码

    如大家所知在注册接口中,手机号参数需要的是未注册的手机号,而在测试用例中,你写入的手机号不一定是未注册的.所以这时需要对注册接口中传入的手机号做处理.下面我就分享一个课程里面学到的一个处理手机号的py ...

  9. [bzoj2326] [洛谷P3216] [HNOI2011] 数学作业

    想法 最初的想法就是记录当前 \(%m\) 值为cur,到下一个数时 \(cur=cur \times 10^x + i\) n这么大,那就矩阵乘法呗. 矩阵乘法使用的要点就是有一个转移矩阵会不停的用 ...

  10. 「 从0到1学习微服务SpringCloud 」12 Zuul的综合使用

    上次讲了Zuul的基本使用,这篇讲的是综合使用,比如过滤器,限流,鉴权等应用 这里继续使用api-getway这个项目 过滤器 实现token验证(前置过滤器) 1.新建一个类,继承ZuulFilte ...