什么是OpenResty

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

  • 路由控制
  • 高并发入口
  • 动态服务降级
  • 动态负载均衡
  • WAF应用防火墙

安装OpenResty

  • 二进制安装

    1
    2
    3
    [root@localhost ~]# yum-config-manager --add-repo https://openresty.org/yum/cn/centos/OpenResty.repo
    [root@localhost ~]# yum install openresty -y
    [root@localhost ~]# systemctl start openresty
  • Docker 安装

    1
    docker run -e KEY_ENV --name proxy --rm -p 443:443 -p 80:80 -v ~/openresty/:/etc/nginx/ docker.io/openresty/openresty:alpine /etc/nginx/startup.sh

Openresty生命周期

生命周期

  • init_by_lua:master-initing阶段,初始化全局配置或模块
  • init_worker_by_lua:worker-initing阶段,初始化进程专用功能
  • ssl_certificate_by_lua:ssl阶段,在“握手”时设置安全证书
  • set_by_lua:rewrite阶段,改写Nginx变量
  • rewrite_by_lua:rewrite阶段,改写URI,实现跳转/重定向
  • access_by_lua:access阶段,访问控制或限速
  • content_by_lua:content阶段,产生响应内容
  • balancer_by_lua:balancer阶段,反向代理时选择upstream
  • header_filter_by_lua:header_filter阶段,加工处理响应头,处理response header
  • body_filter_by_lua:body_filter阶段,加工处理响应体
  • log_by_lua:log阶段,记录日志或其他的收尾工作

通常指定有三种模式:

  1. xx_by_lua: 执行字符串形式的Lua代码
  2. xx_by_lua_block: 功能相同,但指令后是{…}的Lua代码块
  3. xx_by_lua_file: 功能相同,但执行磁盘上的源码文件

Openresty 模块

Openresty组件:http://openresty.org/cn/components.html
社区模块:https://opm.openresty.org/packages
可使用opm工具管理openresty模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# show usage
opm --help

# search package names and abstracts with the user pattern "lock".
opm search lock

# search package names and abstracts with multiple patterns "lru" and "cache".
opm search lru cache

# install a package named lua-resty-foo under the name of some_author
opm get some_author/lua-resty-foo

# get a list of lua-resty-foo packages under all authors.
opm get lua-resty-foo

# show the details of the installed package specified by name.
opm info lua-resty-foo

# show all the installed packages.
opm list

# upgrade package lua-resty-foo to the latest version.
opm upgrade lua-resty-foo

# update all the installed packages to their latest version.
opm update

# uninstall the newly installed package
opm remove lua-resty-foo

例如,下载ledgetech/lua-resty-http模块:

1
2
3
4
5
6
7
4576e3cdb5be:/usr/local/openresty/# opm get ledgetech/lua-resty-http
* Fetching ledgetech/lua-resty-http
Downloading https://opm.openresty.org/api/pkg/tarball/ledgetech/lua-resty-http-0.17.1.opm.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 20622 100 20622 0 0 40595 0 --:--:-- --:--:-- --:--:-- 40594
Package ledgetech/lua-resty-http 0.17.1 installed successfully under /usr/local/openresty/site/ .

Openresty 共享数据

使用ngx.shared实现不同请求间的数据共享

  1. 在nginx.conf配置http模块下初始化共享块,并加载自定义lua模块
    1
    2
    3
    4
    http {
    lua_shared_dict my_cache 1m;
    lua_package_path "/etc/nginx/lua/?.lua;;";
    }
  2. 新建cache模块
    在/etc/nginx/lua/cache.lua中新建cache模块
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    local _M = {}
    function _M.get(key)
    local cache_ngx = ngx.shared.my_cache
    local value = cache_ngx:get(key)
    return value
    end

    function _M.set(key, value, exptime)
    if not exptime then
    exptime = 0
    end

    local cache_ngx = ngx.shared.my_cache
    local succ, err, forcible = cache_ngx:set(key, value, exptime)
    return succ
    end

    return _M
  3. 在业务逻辑中使用cache模块
    1
    2
    3
    4
    5
    6
    local cache = require("cache")
    local cacheExpireTime = 1800

    local maglevToken = ""
    cache.set("MaglevToken", maglevToken, cacheExpireTime)
    maglevToken = cache.get("MaglevToken")

Openresty 调用外部接口

使用resty.http模块: https://github.com/ledgetech/lua-resty-http

1
2
3
4
5
6
7
8
9
10
11
12
13
local httpc = require("resty.http").new()
local uri = "https://" .. appHostIP .. "/data.json"

local res, err = httpc:request_uri(uri, {
method = "GET",
ssl_verify = false,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Host"] = appHostName,
}
})
data = json.decode(res.body)
print(data.data)

Lua 语法

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
w3cschool lua基本语法
lua参考手册