OpenResty® 入门学习记录

OpenResty® 入门学习使用


OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty 安装

运行环境:CentOS 7.2

wget https://openresty.org/download/openresty-1.13.6.2.tar.gz
tar -xzvf openresty-1.13.6.2.tar.gz
./configure  # 默认, --prefix=/usr/local/openresty 程序会被安装到/usr/local/openresty目录。
make
make install

与安装Nginx 一样需要确定已经安装了依赖:pcre、zlib、openssl ,可查看《Nginx 模块开发简单了解》

OpenResty 的Hello World

创建测试目录

mkdir ~/work
cd ~/work
mkdir logs/ conf/

创建配置文件

conf/nginx.conf其中包含以下内容:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    server {
        listen 8080;
        location / {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>Hello, World</p>")
            ';
        }
    }
}

启动Nginx 服务器

# 添加配置文件到nginx # 就已经直接启动nginx
/sbin/nginx -c /usr/local/openresty/work/conf/nginx.conf

测试访问

使用curl 访问本地的Web服务

curl http://localhost:8080/
# 返回信息:<p>Hello, World</p>
# 发现启动之后 -s stop 关不掉  ,只好使用ps -ef | grep nginx ,kill -9 nginx ε=(´ο`*)))唉

到这里,Hello World 完成了 ヾ(@@)ノ


OpenResty 常用API

获取请求参数1

ngx.say() : 直接返回请求结果

ngx.var.arg_key : 获取请求中key参数的vaule

 location / {
            default_type text/html;
            content_by_lua '
                ngx.say(ngx.var.arg_b)  # 这里参数arg_参数key
            ';
        }
# 访问:http://192.168.1.251:8080/lua_var?a=323&b=333333
# 返回:333333

获取请求参数2

  • ngx.req.get_uri_args 获取在uri上的get类型参数,返回的是一个table类型的数据结构。
  • ngx.req.read_body 读取body,这在解析body之前,一定要先读取body。
  • ngx.req.get_post_args 获取form表单类型的参数,返回结果是一个table类型的数据。
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) do
   ngx.say("[GET ] key:", k, " v:", v)
end

ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
   ngx.say("[POST] key:", k, " v:", v)
end
-- 访问:http://192.168.1.251:8080/lua_var?b=323&c=333333
-- 返回:[GET ] key:b v:323 [GET ] key:c v:333333

可以直接在 content_by_lua '....代码.....';

也可以新建一个单独的文件test.lua,使用content_by_lua_file /usr/example/lua/lua_request.lua;

获取请求头

local headers = ngx.req.get_headers()
ngx.say("headers begin", "<br/>")
ngx.say("Host : ", headers["Host"], "<br/>")
ngx.say("user-agent : ", headers["user-agent"], "<br/>")
ngx.say("user-agent : ", headers.user_agent, "<br/>")
for k,v in pairs(headers) do
    if type(v) == "table" then
        ngx.say(k, " : ", table.concat(v, ","), "<br/>")
    else
        ngx.say(k, " : ", v, "<br/>")
    end
end

返回结果:

Host : 192.168.1.251:8080
user-agent : Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
user-agent : Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
host : 192.168.1.251:8080
accept-language : zh-CN,zh;q=0.9
accept-encoding : gzip, deflate
user-agent : Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
connection : keep-alive
accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
cache-control : max-age=0
upgrade-insecure-requests : 1

获取http其他信息的方法

  • ngx.req.http_version() 获取http版本
  • ngx.req.get_method() 获取请求方法(GET、POST等)
  • ngx.req.raw_header() 原始的请求头内容
  • ngx.req.get_body_data() 请求的body内容体

测试结果:ngx.req.http_version : 1.1

ngx.req.get_method : GET

ngx.req.raw_header : GET /lua_var?b=323&c=333333 HTTP/1.1 Host: 192.168.1.251:8080 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9

ngx.req.get_body_data() : nil

输出响应

ngx.header.a="1"      --ngx.header 向响应头输出内容
ngx.header.b={"a","b"}    
ngx.say("hello","</br>")  --ngx.say 输出响应体
ngx.print("sss")      --ngx.print输出响应体
return ngx.exit(200)    --ngx.exit 指定http状态码退出

日志输出

ngx.log(ngx.ERR, "log",log)  --参数:日志级别,key,vaule

重定向

ngx.redirect("http://www.baidu.com", 302)

共享内存

在http模块加上以下:

lua_shared_dict shared_data 1m;
local shared_data = ngx.shared.shared_data
local i = shared_data:get("i")
if not i then
  i = 1
  shared_data:set("i",i)
end
i = shared_data:incr("i",1)
ngx.say("i:",i)

多次访问,浏览器打印:

i:1
i:2
i:3
i:4
i:5

执行结束返回

ngx.exit

用法: ngx.exit(status)
执行上下文: rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, ngx.timer., balancer_by_lua, ssl_certificate_by_lua*
ngx.exit()的使用相对简单些:

  • 当传入的status >= 200(200即为ngx.HTTP_OK),ngx.exit() 会中断当前请求,并将传入的状态码(status)返回给nginx。
  • 当传入的status == 0(0即为ngx.OK)则 ngx.exit() 会中断当前执行的phrase(ngx-lua模块处理请求的阶段,如content_by_lua*),进而继续执行下面的phrase。
  • 对于 ngx.exit() 需要进一步注意的是参数status的使用,status可以传入ngx-lua所定义的所有的HTTP状态码常量(如:ngx.HTTP_OK、ngx.HTTP_GONE、ngx.HTTP_INTERNAL_SERVER_ERROR等)和两个ngx-lua模块内核常量(只支持NGX_OK和NGX_ERROR这两个,如果传入其他的如ngx.AGAIN等则进程hang住)。
  • 文档中推荐的 ngx.exit() 最佳实践是同 return 语句组合使用,目的在于增强请求被终止的语义(return ngx.exit(...))。

关于Lua以及ab压力测试

Lua 注意的事项

下标从 1 开始,这个是和其他编程语言很大的不同。

不区分 array 和 dict ,会导致处理 json 的时候,无法区分 array 和 object。

默认全局变量,需要在所有变量前加 local,忘记的话,可能导致各种难查的 bug。

自带的字符串正则匹配规则和通常的 PCRE 不同,使用的话,学习成本较高。

Lua 标准库和周边库,都是阻塞的,需要自己甄别哪些可以和 OpenResty 搭配使用。新手很容易使用了阻塞的库,而导致性能急剧下降。

ab压力测试

所以,由于线上的 Nginx 可能面对的是高并发场景,对于自己的 Lua 代码最好做个压力测试 ,例子:

# ab的全称是Apache Bench,是Apache自带的网络压力测试工具
yum -y install httpd-tools
# -n 执行的请求数量
# -c 并发请求个数
ab -n 1000 -c 100 http://www.baidu.com/

深入学习方向

​ Openresty的基础就是以上这些了,其他的就是LUA语言的东东了。

​ 深入学习的话,Openresty官网有许多开源的组件:连接Mysql的LuaRestyMySQLLibrary 、连接Redis的LuaRestyRedisLibrary 等等,有好多好多。有使用需求的时候去研究一下就可以了,这些的文档都写的非常的全了。


参考资料

官网:http://openresty.org/cn/

博客:https://blog.csdn.net/forezp/article/details/78616856


小杭 (^U^)ノ~YO
在这里插入图片描述

posted @ 2022-05-21 23:34  小-杭  阅读(46)  评论(0编辑  收藏  举报