🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 概述 OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。 OpenResty 目标是让Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。 虽然 OpenResty 的核心是 Nginx,但它又超越了 Nginx,关键就在于其中的 ngx_lua 模块,把小巧灵活的 Lua 语言嵌入了 Nginx,可以用脚本的方式操作 Nginx 内部的进程、多路复用、阶段式处理等各种构件。 脚本语言的好处你一定知道,它不需要编译,随写随执行,这就免去了 C 语言编写模块漫长的开发周期。而且 OpenResty 还把 Lua 自身的协程与 Nginx 的事件机制完美结合在一起,优雅地实现了许多其他语言所没有的“同步非阻塞”编程范式,能够轻松开发出高性能的 Web 应用。 目前 OpenResty 有两个分支,分别是开源、免费的“OpenResty”和闭源、商业产品的“OpenResty+”,运作方式有社区支持、OpenResty 基金会、OpenResty.Inc 公司,还有其他的一些外界赞助(例如 Kong、CloudFlare),正在蓬勃发展。 ![](https://img.kancloud.cn/19/ce/19ce8878687f8f9e4e35e020861f3e11_1056x559.png) > OpenResty主要包含技术 * Nginx:一款轻量级、高性能、高并发的Web服务器。 * Lua:一种轻量、小巧、可移植、快速的脚本语言;LuaJIT即时编译器会将频繁执行的Lua代码编译成本地机器码交给CPU直接执行,执行效率更高,OpenResty 会默认启用 LuaJIT。 官方网站:[http://openresty.org/](http://openresty.org/) ## 动态Lua脚本 OpenResty 里的一个关键模块是 ngx\_lua,它为 Nginx 引入了脚本语言 Lua。Lua 是一个比较“小众”的语言,虽然历史比较悠久,但名气却没有 PHP、Python、JavaScript 大,这主要与它的自身定位有关。 ![](https://img.kancloud.cn/3a/e0/3ae04457e1cd5ea39efb3f0a339ffb90_1142x641.png) Lua 的设计目标是嵌入到其他应用程序里运行,为其他编程语言带来“脚本化”能力,所以它的“个头”比较小,功能集有限,不追求“大而全”,而是“小而美”,大多数时间都“隐匿”在其他应用程序的后面,是“无名英雄”。 你或许玩过或者听说过《魔兽世界》《愤怒的小鸟》吧,它们就在内部嵌入了 Lua,使用 Lua 来调用底层接口,充当“胶水语言”(glue language),编写游戏逻辑脚本,提高开发效率。 OpenResty 选择 Lua 作为“工作语言”也是基于同样的考虑。因为 Nginx C 开发实在是太麻烦了,限制了 Nginx 的真正实力。而 Lua 作为“最快的脚本语言”恰好可以成为 Nginx 的完美搭档,既可以简化开发,性能上又不会有太多的损耗。 作为脚本语言,Lua 还有一个重要的“代码热加载”特性,不需要重启进程,就能够从磁盘、Redis 或者任何其他地方加载数据,随时替换内存里的代码片段。这就带来了“动态配置”,让 OpenResty 能够永不停机,在微秒、毫秒级别实现配置和业务逻辑的实时更新,比起 Nginx 秒级的重启是一个极大的进步。 ## 高效 Lua 脚本 OpenResty 能够高效运行的一大“秘技”是它的“同步非阻塞”编程范式,如果你要开发 OpenResty 应用就必须时刻铭记于心。 “同步非阻塞”本质上还是一种“多路复用”,拿上一讲的 Nginx epoll 来对比解释一下。epoll 是操作系统级别的“多路复用”,运行在内核空间。而 OpenResty 的“同步非阻塞”则是基于 Lua 内建的“协程”,是应用程序级别的“多路复用”,运行在用户空间,所以它的资源消耗要更少。 OpenResty 里每一段 Lua 程序都由协程来调度运行。和 Linux 的 epoll 一样,每当可能发生阻塞的时候“协程”就会立刻切换出去,执行其他的程序。这样单个处理流程是“阻塞”的,但整个 OpenResty 却是“非阻塞的”,多个程序都“复用”在一个 Lua 虚拟机里运行。 ![](https://img.kancloud.cn/c8/b8/c8b87eb1ef029638bad0f5c039e2349b_1520x596.png) 下面的代码是一个简单的例子,读取 POST 发送的 body 数据,然后再发回客户端: ```lua ngx.req.read_body() -- 同步非阻塞(1) local data = ngx.req.get_body_data() if data then ngx.print("body: ", data) -- 同步非阻塞(2) end ``` 代码中的`ngx.req.read_body`和`ngx.print`分别是数据的收发动作,只有收到数据才能发送数据,所以是`同步`的。 但即使因为网络原因没收到或者发不出去,OpenResty 也不会在这里阻塞`干等着`,而是做个`记号`,把等待的这段 CPU 时间用来处理其他的请求,等网络可读或者可写时再`回来`接着运行。 假设收发数据的等待时间是 10 毫秒,而真正 CPU 处理的时间是 `0.1` 毫秒,那么 OpenResty 就可以在这 `10` 毫秒内同时处理 `100` 个请求,而不是把这 `100` 个请求阻塞排队,用 `1000` 毫秒来处理。 除了`同步非阻塞`,OpenResty 还选用了 LuaJIT 作为 Lua 语言的`运行时(Runtime)`,进一步“挖潜增效”。 LuaJIT 是一个高效的 Lua 虚拟机,支持 JIT(Just In Time)技术,可以把 Lua 代码即时编译成`本地机器码`,这样就消除了脚本语言解释运行的劣势,让 Lua 脚本跑得和原生 C 代码一样快。 另外,LuaJIT 还为 Lua 语言添加了一些特别的增强,比如二进制位运算库 bit,内存优化库 table,还有 FFI(Foreign Function Interface),让 Lua 直接调用底层 C 函数,比原生的压栈调用快很多。 ## OpenResty 安装 > OpenResty 中文官网:https://openresty.org/cn/ #### 安装前的准备 您必须将这些库`perl 5.6.1+`,`libpcre`,`libssl`安装在您的电脑之中。 对于 Linux来说, 您需要确认使用`ldconfig`命令,让其在您的系统环境路径中能找到它们。 **Debian 和 Ubuntu 用户** 推荐您使用 apt-get安装以下的开发库: ``` apt-get install libpcre3-dev libssl-dev perl make build-essential curl ``` #### 构建 OpenResty **下载** 从下载页https://openresty.org/cn/download.html 下载最新的 OpenResty®源码包,并且像下面的示例一样将其解压: ``` wget https://openresty.org/download/openresty-1.25.3.1.tar.gz tar -xzvf openresty-1.25.3.1.tar.gz ``` **./configure** 然后在进入`openresty-VERSION/`目录, 然后输入以下命令配置: ``` ./configure ``` 默认,`--prefix=/usr/local/openresty`程序会被安装到/usr/local/openresty目录。您可以指定各种选项,比如 ``` ./configure --prefix=/opt/openresty \ --with-luajit \ --without-http_redis2_module \ --with-http_iconv_module \ --with-http_postgres_module ``` 本次编译配置 ``` ./configure --prefix=/usr/local/openresty \ --with-luajit \ --without-http_redis2_module \ --with-http_iconv_module \ --with-http_stub_status_module \ --with-http_xslt_module ``` **make** 您可以使用下面的命令来编译: ~~~bash make ~~~ 如果您的电脑支持多核`make`工作的特性, 您可以这样编译: ~~~bash make -j2 ~~~ 假设您是的机器是双核。 **make install** 如果前面的步骤都没有问题的话,您可以使用下面的命令安装[OpenResty](https://openresty.org/cn/openresty.html "OpenResty")到您的系统中: ~~~bash make install ~~~ 在 Linux 上,通常需要使用`sudo`来获取 root 权限来完成安装。 安装成功后,查看版本号 ``` /usr/local/openresty/nginx/sbin/nginx -v nginx version: openresty/1.25.3.1 ``` #### 设置变量 默认情况下,OpenResty安装在前缀`/usr/local/openresty/`中。 最后,您需要将OpenResty提供的命令行实用程序添加到PATH环境中,如下所示: ``` export PATH=/usr/local/openresty/bin:/usr/local/openresty/nginx/sbin:$PATH ``` 如果您正在使用bash。最好将此行添加到Shell的启动脚本中,例如`〜/ .bashrc`或`〜/ .bash_profile`。 或者以下方式 ``` [ -z "`grep ^'export PATH=' /etc/profile`" ] && echo "export PATH=/usr/local/openresty/nginx/sbin:\$PATH" >> /etc/profile [ -n "`grep ^'export PATH=' /etc/profile`" -a -z "`grep /usr/local/openresty/ /etc/profile`" ] && sed -i "s@^export PATH=\(.*\)@export PATH=/usr/local/openresty/nginx/sbin:\1@" /etc/profile . /etc/profile ``` 后面就可以用`nginx -t` 检测配置是否正确,`nginx -s reload` 重载 Nginx 了。 ## 设置服务和开机启动 创建`/etc/systemd/system/openresty.service`文件,内容: ```conf [Unit] Description=A dynamic web platform based on Nginx and LuaJIT. After=network.target [Service] Type=forking PIDFile=/run/openresty.pid ExecStartPre=/usr/local/openresty/bin/openresty -t -q -g 'daemon on; master_process on;' ExecStart=/usr/local/openresty/bin/openresty -g 'daemon on; master_process on;' ExecReload=/usr/local/openresty/bin/openresty -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/openresty.pid TimeoutStopSec=5 KillMode=mixed [Install] WantedBy=multi-user.target ``` 重新加载 systemd 服务,以便它可以找到我们的文件: ``` systemctl daemon-reload ``` 通过 systemd 重启 OpenResty: ``` systemctl restart openresty ``` 设置开机启动: ``` systemctl enable openresty ``` 查看服务 ``` systemctl status openresty.service ``` ![](https://img.kancloud.cn/af/36/af364908ff5bfa6674b1928fa3e73cfe_1411x262.png) 以上表示Openresty安装成功