OpenResty介绍
OpenResty 是一个兼具开发效率和性能的服务端开发平台,虽然它基于 NGINX 实现,但其适用范围早已远远超出反向代理和负载均衡。它的核心是基于 NGINX 的一个 C 模块(lua-nginx-module),该模块将 LuaJIT 嵌入到 NGINX 服务器中,并对外提供一套完整的 Lua API,透明地支持非阻塞 I/O,提供了轻量级线程、定时器等高级抽象。同时,围绕这个模块,OpenResty 构建了一套完备的测试框架、调试技术以及由 Lua 实现的周边功能库。
可以用 Lua 语言来进行字符串和数值运算、查询数据库、发送 HTTP 请求、执行定时任务、调用外部命令等,还可以用 FFI 的方式调用外部 C 函数。这基本上可以满足服务端开发需要的所有功能。
OpenResty支持协程,并基于此实现了同步非阻塞的编程模式。掌握好了 OpenResty,就可以同时拥有脚本语言的开发效率和迭代速度,以及 NGINX C 模块的高并发和高性能优势。
传统的Web服务器,如NGINX,如果发生任何变动,都需要去修改磁盘上的配置文件,然后重新加载才能生效。OpenResty是由脚本语言Lua来控制逻辑的,可以动态的控制路由、上游、ssl证书、请求、响应等。设置可以在不重启OpenResty的前提下修改业务的处理逻辑。
学习OpenResty有一下几个重点:
- 同步非阻塞的编程模型
- 不同阶段的作用
- luaJit和lua的不同之处
- OpenResty API和周边库
- 协程和cosocket
- 单元测试框架和性能测试工具
- 火焰图和周边工具链
- 性能优化
OpenResty的安装
brew tap openresty/brew brew install openresty
安装完 OpenResty 后,默认就已经把 OpenResty 的 CLI:resty 安装好了。resty是个 1000 多行的 Perl脚本,OpenResty 的周边工具都是 Perl 编写的,这个是由 OpenResty 作者的技术偏好决定的。
$ which resty /usr/local/bin/resty $ head -n 1 /usr/local/bin/resty #!/usr/bin/env perl
hello world
至少需要三步才能完成:
- 创建工作目录;
- 修改 NGINX 的配置文件,把 Lua 代码嵌入其中;
- 启动 OpenResty 服务。
下面是一个最简化的 nginx.conf,在根目录下新增 OpenResty 的content_by_lua指令,里面嵌入了ngx.say的代码:
events { worker_connections 1024; } http { server { listen 8080; location / { content_by_lua ' ngx.say("hello, world") '; } } }
将 Lua 代码从 nginx.conf 里面抽取出来,保持代码的可读性和可维护性:
在工作根目录下创建一个名为 lua 的目录,专门用来存放代码
然后修改 nginx.conf 的配置,把 content_by_lua_block 改为 content_by_lua_file:
events { worker_connections 1024; } http { server { listen 8080; location / { content_by_lua_file lua/hello.lua; } } }
重启 OpenResty 的服务
$ sudo kill -HUP `cat logs/nginx.pid`
如果原本给出的是相对路径,那么 OpenResty 在启动时,会把OpenResty 启动的命令行参数中的 -p PATH 作为前缀,将相对路径拼接为绝对路径。这样,自然就可以顺
利找到Lua 文件。
Lua 代码在第一个请求时会被加载,并默认缓存起来。所以在每次修改 Lua 源文件后,都必须重新加载 OpenResty 才会生效。其实,在 nginx.conf 中关闭 lua_code_cache 就能避免重新加载。不过,特别需要注意的是,这种方法只能临时用于开发和调试,如果是线上部署,一定要记得打开缓存,否则会非常影响性能。
OpenResty 提供了 lua_package_path 指令,可以设置 Lua 模块的查找路径。针对上面的例子,可以把 lua_package_path 设置为 $prefix/lua/?.lua;;,其中:
- $prefix就是启动参数中的 -p PATH;
- /lua/?.lua表示 lua 目录下所有以 .lua 作为后缀的文件;
- 最后的两个分号,则代表内置的代码搜索路径。
OpenResty安装后的目录
先通过 -V 选项,查看 OpenResty 安装到了哪一个目录
安装目录下的文件夹:
最重要的 bin 目录:
这里面既有 OpenResty CLI resty,也有最核心的可执行文件 openresty,它其实是nginx 的一个软链接。
至于目录里面其他的一些工具,没有任何悬念,它们和 resty 一样,都是 Perl 脚本。
在这其中,opm 是包管理工具,可以通过它来管理各类第三方包,是 OpenResty 提供的文档查看工具,你可以通过它来查看 OpenResty 和 NGINX 的使用文档:
nginx 和 luajit 这两个目录。这两个很好理解,主要存放 NGINX 和 LuaJIT 的可执行文件和依赖,是 OpenResty 的基石。很多人说 OpenResty 基于 Lua,这个说法其实并不准确,从上面我们可以看出, OpenResty 其实是基于 LuaJIT的。
lualib 目录。它里面存放的是 OpenResty 中使用到的 Lua 库,主要分为 ngx 和 resty 两个子目录。
前者存放的是 lua-resty-core 这个官方项目中的 Lua 代码,里面都是基于 FFI 重新实现的 OpenRestyAP
而 resty 目录中存放的则是各种 lua-resty-* 项目包含的 Lua 代码。