OpenResty简介及学习笔记

  • 摘要
  • 简介
  • 一、OpenResty综述
  • 二、指令说明:
    • *_by_lua
    • *_by_lua_block {lua_script}
    • *_by_lua_file
  • 三、登陆验证
    • IP防火墙
    • 操作头信息检测
    • 登陆缓存
    • 过滤参数
  • 四、输出过滤
    • header_filter_by_lua*
    • body_filter_by_lua*
  • 五、Redis

摘要

OpenResty系列文章之一。

前些日子做的一些研究,期间收获了一些对web后台应用的理解,nginx运行机理的部分理解。

本篇包括简介、部分模块的介绍。

简介

OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器。它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。

通过众多进行良好设计的 Nginx 模块,OpenResty 有效地把 Nginx 服务器转变为一个强大的 Web 应用服务器,基于它开发人员可以使用Lua 编程语言对 Nginx 核心以及现有的各种Nginx C 模块进行脚本编程,构建出可以处理一万以上并发请求的极端高性能的 Web 应用。

OpenResty 致力于将你的服务器端应用完全运行于 Nginx 服务器中,充分利用 Nginx 的事件模型来进行非阻塞 I/O 通信。不仅仅是和 HTTP 客户端间的网络通信是非阻塞的,与MySQL、PostgreSQL、Memcached、以及 Redis 等众多远方后端之间的网络通信也是非阻塞的。

因为 OpenResty 软件包的维护者也是其中打包的许多 Nginx 模块的作者,所以 OpenResty 可以确保所包含的所有组件可以可靠地协同工作。

作者简介:

agentzh,本名章亦春,现任 CloudFare 系统工程师,主要是 Nginx 和 OpenResty 开发,是一名快乐的程序员,现定居美国旧金山。曾经在北京的时候供职于 Yahoo!中国以及淘宝(阿里巴巴)。

教程:agentzh 的 Nginx 教程

其他内容可以参看: OpenResty简介,OpenResty 作者章亦春访谈实录

一、OpenResty综述

OpenResty®通过 Lua 扩展 NGINX 实现的可伸缩的 Web 平台

先扔三个网站:

首先,OpenResty官网!

还有Github:OpenResty

为数不多的书籍:OpenResty最佳实践(Lua语言入门也可以全靠它)

下图给出的是Lua Nginx Module中各指令的执行顺序

  • set_by_lua: 流程分支处理判断变量初始化
  • rewrite_by_lua: 转发、重定向、缓存等功能(例如特定请求代理到外网)
  • access_by_lua: IP 准入、接口权限等情况集中处理(例如配合 iptable 完成简单防火墙)
  • content_by_lua: 内容生成
  • header_filter_by_lua: 应答 HTTP 过滤处理(例如添加头部信息)
  • body_filter_by_lua: 应答 BODY 过滤处理(例如完成应答内容统一成大写)
  • log_by_lua: 会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其他机器)

实际上我们只使用其中一个阶段 content_by_lua,也可以完成所有的处理。但这样做,会让我们的代码比较臃肿,越到后期越发难以维护。把我们的逻辑放在不同阶段,分工明确,代码独立,后期发力可以有很多有意思的玩法。

二、指令说明:

*_by_lua < lua-script-str >

无后缀的指令,后加字符串型的lua程序。

如:

  • location / {
  • default_type text/html;
  • content_by_lua '
  • ngx.say("<p>hello, world</p>")
  • ';
  • }

nginx

*_by_lua_block {lua_script}

有block后缀,可以直接跟lua程序段。

如:

  • location / {
  • content_by_lua_block{
  • local test = 'Hello,world'
  • ngx.say(test)
  • }
  • }

*_by_lua_file < path-to-lua-script-file >

file后缀跟lua文件路径

如:

  • location ~ ^/api/([-_a-zA-Z0-9/]+) {
  • # 准入阶段完成参数验证
  • access_by_lua_file lua/access_check.lua;
  • #内容生成阶段
  • content_by_lua_file lua/$1.lua;
  • }

nginx

三、登陆验证

access_by_lua*中集中进行一些权限认证,防止恶意ip、非法行为进入到服务器中。

  • location / {
  • access_by_lua_block{
  • ngx.exit(ngx.HTTP_FORBIDDEN)
  • }
  • content_by_lua_block{
  • --内容生产阶段
  • }
  • }

IP防火墙

OpenResty最佳实践提到:禁止某些终端访问

上面文档下方推荐第三方包:Github,Lua-resty-iputils

操作头信息检测

通过access_by_lua*可以对请求进行过滤,比如可以在这里检查有没有带authorization头部信息,若没有带可以用ngx.exit()直接退出。

登陆缓存

Github: lua-resty-jwt模块进行jwt校验

结合lua-resty-jwtlua-resty-redis甚至可以将服务器登陆缓存移植到nginx上。

过滤参数

还未尝试。

防止 SQL 注入

四、输出过滤

通常是header_filter_by_lua*body_filter_by_lua*配合实现。

【文档来源官方】:

注意下列API函数现在还不能在set_by_lua*header_filter_by_lua*body_filter_by_lua*log_by_lua*四个环境中使用:

  • 输出API 函数 (e.g., ngx.say and ngx.send_headers)
  • 控制API 函数 (e.g., ngx.redirect and ngx.exec)
  • 子请求API 函数 (e.g., ngx.location.capture and ngx.location.capture_multi)
  • Cosocket API 函数 (e.g., ngx.socket.tcp and ngx.req.socket).

header_filter_by_lua*

使用Lua代码在lua块中定义输出头信息。

example1:

  • location / {
  • proxy_pass http://mybackend;
  • header_filter_by_lua 'ngx.header.Foo = "blah"';
  • }

nginx

example2:

  • header_filter_by_lua_block {
  • ngx.header["content-length"] = nil
  • }

body_filter_by_lua*

参考:

谈谈 OpenResty 中的 body_filter_by_lua*

输入数据块chunks要经过ngx.arg1 (Lua 字符串)的过滤,"eof"标志指示响应体数据流的末端通过ngx.arg2 (Lua bollean值)显示。

这个情景下,"eof"标志就是主请求的last_buf或子请求的 last_in_chain。"eof" == "true" 表示此次nginx请求的响应结束了。

由于响应体可能会分多块发送,body_filter_by_lua*可能会被多次调用。详细机理参考上面文献有提到。

  • location /t {
  • echo hello world;
  • echo hiya globe;
  • body_filter_by_lua '
  • ......
  • ';
  • }

nginx

比如上面,body_filter_by_lua*首次调用时ngx.arg1 的值只是hello world,不包括下面的hiya globe

我验证了一下:

  • location = /test_bf {
  • echo hello world;
  • echo this;
  • echo is;
  • echo world;
  • header_filter_by_lua_block {
  • ngx.header.content_length = nil
  • }
  • body_filter_by_lua_block {
  • if string.match(ngx.arg[1], "this") then
  • ngx.arg[2] = true
  • ngx.arg[1] = "end"
  • return
  • end
  • }
  • }

上述location发送四块数据,匹配到this便设置"eof"不再发送下去了。

  • $ curl

结果:

  • $ hello world
  • $ end

要点:

① ngx.arg[2] = true设置新的"eof"标志使截断响应,设置"eof"依旧是有效的响应。

② ngx.arg[1] = "end"修改ngx.arg[1] 的值,即为修改输出响应。而当需要替换一些信息,仅需一行代码即可实现。

  • ngx.arg[1] = ngx.re.gsub(ngx.arg[1], "o", "*")

上文也提到。上述即为将所有 ' o ' 字符替换为 ' * ' 字符

若该location作为其他location的子请求,而作为子请求不想被过滤数据。需要通过ngx.is_subrequest判断。

  • body_filter_by_lua_block {
  • if ngx.arg[1] and not ngx.is_subrequest then
  • ......
  • end
  • }

nginx

还有一点,如果在body_filter_by_lua*中的Lua代码会修改响应体的长度,这就需要去把Content-Length的响应头去除掉。我之前测试与前端联调时,就是发现body过滤必须要字符数相同才会显示,很头疼不知道什么原因。其实只要去掉这个头就行了。

  • location = / {
  • proxy_pass ......
  • header_filter_by_lua_block {
  • ngx.header.content_length = nil
  • }
  • body_filter_by_lua_block {
  • ngx.arg[1] = ngx.re.gsub(ngx.arg[1], "o", "**")
  • }
  • }

五、Redis

官方github:lua-resty-redis

OpenResty最佳实践:访问有授权验证的 Redis

官方包封装了一些Redis的方法,使用起来还是挺舒适的。

本文链接:https://blog.maozhiting.com/post/openresty_notes.html

-- EOF --

作者 毛毛 发表于 2017-11-05 15:11:55 ,并被添加「 OpenResty 」标签 ,最后修改于 2017-11-05 15:47:30

OpenResty简介及学习笔记相关推荐

  1. 不完全免疫算法简介MOIA-DCSS--AIS学习笔记8

    不完全免疫算法简介MOIA-DCSS–AIS学习笔记8 觉得有用的话,欢迎一起讨论相互学习~ 多目标优化 A novel MOIA with a decomposition-based clonal ...

  2. 不完全免疫算法简介HEIA--AIS学习笔记2

    不完全免疫算法简介HEIA–AIS学习笔记2 觉得有用的话,欢迎一起讨论相互学习~ 多目标优化 A Hybrid AIS for MOP 参考文献 A Hybrid Evolutionary Immu ...

  3. 不完全免疫算法简介AIMA--AIS学习笔记7

    不完全免疫算法简介AIMA–AIS学习笔记7 觉得有用的话,欢迎一起讨论相互学习~ 多目标优化 An adaptive MOIAs with multiple DE 参考文献 An adaptive ...

  4. 不完全免疫算法简介DMMO--AIS学习笔记3

    不完全免疫算法简介DMMO–AIS学习笔记3 觉得有用的话,欢迎一起讨论相互学习~ 多目标优化 A double-module immune algorithm for MOP 参考文献 A doub ...

  5. 不完全免疫算法简介IMADE--AIS学习笔记5

    不完全免疫算法简介IMADE–AIS学习笔记5 觉得有用的话,欢迎一起讨论相互学习~ 多目标优化 An immune MOP algorithm with DE inspired recombinat ...

  6. 不完全免疫算法简介AU-DHEIA--AIS学习笔记6

    不完全免疫算法简介AU-DHEIA–AIS学习笔记6 觉得有用的话,欢迎一起讨论相互学习~ 多目标优化 An adaptive hybrid MOIA based on uniform distrib ...

  7. 1.0 深度学习回顾与PyTorch简介 - PyTorch学习笔记

    P1 深度学习回顾与PyTorch简介 视频课程地址:点我 fly~~~ 本节课主要偏向于NLP,因为作者本人是做NLP方向NLP 预训练三种模型: BERT OpenAI GPT ELMo [NLP ...

  8. 【CS231n】五、卷积神经网络简介CNN学习笔记_一只神秘的大金毛_新浪博客

    1.历史简介 The Mark 1 Perceptron machine was the first implementation of the perceptron algorithm.  其只有f ...

  9. 【CS231n】五、卷积神经网络简介CNN学习笔记

    1.历史简介 The Mark 1 Perceptron machine was the first implementation of the perceptron algorithm.  其只有f ...

最新文章

  1. HDU - 3911 Black And White 区间翻转+区间连续最长
  2. UVA11825: Hackers' Crackdown (状压dp)
  3. 电信业务分类目录2019_2019年7月国内增值电信业务许可情况分析报告:本期重点介绍内容分发网络业务...
  4. Python3 输入和输出
  5. NASM汇编语言与计算机系统04-实模式-屏幕显示不定长度的字符串(cmp/je)
  6. ubuntu挂载共享文件
  7. Java基础---其他对象
  8. Asp.Net基于forms的验证机制,记录一下...
  9. 从“外行”到“里手”,长沙企业“力量矩阵”开始觉醒
  10. 服务器带的虚拟软驱有什么用,云服务器是干什么用的?摩杜云带你去了解!
  11. 集成运算放大器的简要介绍
  12. Mac 生成ico图标
  13. 手机输入法哪家好用?用户目前最喜爱这4款,有你正在使用的吗
  14. 字节跳动员工基本年薪曝光:最高 254 万元
  15. 如何用Java画一棵简单的圣诞树
  16. oracle 创建新的表空间,oracle创建表空间新建新用户并受权
  17. C++的输入、输出与文件
  18. 【问题解决】Selenium——NoSuchWindowException: Browsing context has been discarded
  19. Hive数据连接与函数(2)
  20. MFC实现简单连续加减计算器

热门文章

  1. DB2更改数据文件路径
  2. Linux版本之挑选适合服务器的OS发行版
  3. cocos工程里面“”invalid ''cobl” in fuction xxx原理与解决方案
  4. CodeForces - 17E Palisection(回文自动机/Palindrome Series优化dp)
  5. CodeForces - 222C Reducing Fractions(唯一分解定理)
  6. PAT (Advanced Level) 1003 Emergency(最短路+动态规划)
  7. python遍历文件对象_Python文件常见操作实例分析【读写、遍历】
  8. UVA - 10384The Wall Pushers推门游戏(迭代加深)
  9. 自学Java5.19
  10. 数据科学竞赛-人脸表情识别