OpenResty Introduction and study notes

OpenResty Introduction and study notes

Summary

OpenResty one of a series of articles.

Some time ago to do some research during harvest some background understanding of web applications, some understanding of the mechanisms of the nginx.

This chapter cover introduction, Part module.

Brief introduction

logo

OpenResty  (also known as  ngx_openresty ) is a full-featured Web application server. It is packaged with a standard  Nginx core , many of the commonly used third-party modules , as well as most of their dependencies.

enter description here

Carried out by a number of well-designed Nginx module, OpenResty effectively put Nginx server into a powerful Web application server , based on which developers can use the Lua programming language to Nginx core as well as the various existing Nginx C modules scripting , building that can handle extremely high-performance Web applications more than ten thousand concurrent requests.

OpenResty committed to your server-side application is fully running on Nginx server, Nginx take full advantage of the event model to perform non-blocking I / O communication . And network communication not only between HTTP client is non-blocking, the number of network communications between a rear end remote MySQL, PostgreSQL, Memcached, Redis and the like and are non-blocking.

Because OpenResty package maintainer is also one of many Nginx modules packaged, so OpenResty to ensure that all components can be included reliably work together.

About the Author:

agentzh , whose real name is Zhang also spring, the incumbent CloudFare system engineers, mainly OpenResty Nginx and development, is a happy programmer and now lives in San Francisco. In Beijing, when once worked at Yahoo! China and Taobao (Ali Baba).

Tutorial: agentzh of Nginx tutorials

Else can see:  OpenResty Profile , OpenResty chapter of the interview also spring

A, OpenResty review

 

 

 

 

OpenResty® NGINX achieved through Lua extension scalable Web platform


To throw three sites:

 

First, OpenResty official website!

There Github: OpenResty

One of the few books: OpenResty Best Practices (entry Lua language can also depend on it)

The following figure shows the order of execution of each instruction in Lua Nginx Module of

alt

  • 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 Best Practices: access authorization verification has Redis

The official number of packet encapsulation Redismethod, use is still very comfortable.

This link: https://blog.maozhiting.com/post/openresty_notes.html

-- EOF --

Author  毛毛 published in  2017-11-05 15:11:55  , and added, "  OpenResty " label, last modified  2017-11-05 15:47:30

Guess you like

Origin blog.csdn.net/ai2000ai/article/details/95312366