如何在Ubuntu16.04上为Nginx使用OpenRestyWeb框架
介绍
OpenResty 是一个 Web 服务器,它通过将 Nginx 与许多有用的 Nginx 模块和 Lua 库捆绑在一起来扩展 Nginx。 OpenResty 擅长扩展 Web 应用程序和服务。 例如,它包含的一个模块使您能够编写直接在 Nginx 工作程序中执行的 Lua 代码,从而实现高性能应用程序。
在本指南中,您将从源代码设置 OpenResty; 某些发行版的预构建软件包可能已过时。 您还将探索一些具有 OpenResty 独特功能的简单示例应用程序。
先决条件
要遵循本指南,您将需要:
- 按照 Initial Server Setup with Ubuntu 16.04 教程设置一台 Ubuntu 16.04 服务器,包括 sudo 非 root 用户和防火墙。
注意 Nginx 应该安装 而不是 。 它包含在 OpenResty 中,提前安装会发生冲突。
第 1 步 — 下载 OpenResty 的源代码和依赖项
在本节中,我们将从源代码安装 OpenResty。
首先,从 OpenResty 网站的 Download 页面找到最新的 OpenResty 源代码发布。 下载 tarball,确保将版本号替换为最新版本(如果已更改)。
wget https://openresty.org/download/openresty-1.11.2.2.tar.gz
同时下载 PGP 密钥文件,以便我们验证文件的内容。
wget https://openresty.org/download/openresty-1.11.2.2.tar.gz.asc
接下来,我们需要添加下载页面上列出的作者的公钥。 在撰写本文时,这是公钥 A0E98066
。 但是,请检查它是否已更改; 它列在同一下载页面上。
gpg --keyserver pgpkeys.mit.edu --recv-key A0E98066
您应该看到以下输出(用您的用户名代替 sammy):
Outputgpg: directory `/home/sammy/.gnupg' created gpg: new configuration file `/home/sammy/.gnupg/gpg.conf' created gpg: WARNING: options in `/home/sammy/.gnupg/gpg.conf' are not yet active during this run gpg: keyring `/home/sammy/.gnupg/secring.gpg' created gpg: keyring `/home/sammy/.gnupg/pubring.gpg' created gpg: requesting key A0E98066 from hkp server pgpkeys.mit.edu gpg: /home/sammy/.gnupg/trustdb.gpg: trustdb created gpg: key A0E98066: public key "Yichun Zhang (agentzh) <agentzh@gmail.com>" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)
检查公钥上的名称(在本例中为“Yichun Zhang”)是否与 OpenResty 网站上列出的名称匹配。
现在,检查签名文件是否与下载的 .tar.gz
文件匹配。
gpg openresty-1.11.2.2.tar.gz.asc
您将看到以下输出:
Outputgpg: assuming signed data in `openresty-1.11.2.2.tar.gz' gpg: Signature made Thu 17 Nov 2016 10:24:29 PM UTC using RSA key ID A0E98066 gpg: Good signature from "Yichun Zhang (agentzh) <agentzh@gmail.com>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 2545 1EB0 8846 0026 195B D62C B550 E09E A0E9 8066
您看到的警告是因为您没有亲自验证此密钥是否属于所有者(即,您没有使用自己的私钥对公钥进行签名)。 没有一种简单的方法可以完全保证此公钥属于所有者,它不完全受信任。
但是,在这种情况下,Good signature 表明该文件确实是 OpenResty 的作者打算分发的文件,因此我们可以继续安装。
接下来,提取下载的文件并移动到新创建的目录中。
tar -xvf openresty-1.11.2.2.tar.gz cd openresty-1.11.2.2
我们需要安装必要的工具来编译 OpenResty。 有关从源代码编译程序的更多信息,请参阅 this tutorial about using make to install packages from source。
sudo apt-get install build-essential
我们还需要安装一些其他的包:
- readline:这将被 OpenResty 用于命令行界面。
- ncurses:这是 OpenResty 将用于其命令行界面的另一个软件。
- PCRE:该软件将为 OpenResty 提供正则表达式功能。
- OpenSSL:OpenSSL 用于安全通信,例如 TLS (HTTPS)。
- Perl:Perl 是一种可以在 OpenResty 中使用的编程语言。
要安装这些软件包,请执行以下命令:
sudo apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl
我们现在拥有构建和安装 OpenResty 所需的所有组件。
第 2 步 — 安装 OpenResty
我们将为 OpenResty 配置 PCRE 正则表达式和 IPv6 支持。 我们还将通过提供 -j2
标志来并行化部分构建过程,这将告诉 make
2 个作业可以同时运行。 该命令将主要测试您的系统上是否所有依赖项都可用,并收集稍后将由构建步骤使用的信息。 它还将已经构建了一些依赖项,例如 LuaJIT。
./configure -j2 --with-pcre-jit --with-ipv6
然后你可以再次通过提供 -j2
标志来构建 OpenResty。 这将编译 OpenResty 本身。
make -j2
最后,您可以安装 OpenResty。 使用 sudo
确保所有文件都可以复制到系统上的正确位置,以便 OpenResty 在运行时可以找到它们。
sudo make install
您需要在防火墙中允许 HTTP 连接才能使 Web 服务器正常工作。
sudo ufw allow http
如果要使用 sudo ufw allow https
,您还可以选择允许 HTTPS。 您可以通过检查其状态来验证防火墙中的更改。
sudo ufw status
您应该在显示的输出中看到允许的 HTTP 流量(端口 80
),如果添加了 HTTPS(端口 443
)。
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80 ALLOW Anywhere 443 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 80 (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6)
您现在可以检查安装是否成功。 首先,启动 OpenResty。
sudo /usr/local/openresty/bin/openresty
如果命令成功,它将立即完成而不输出文本。 在这种情况下,您可以在浏览器中访问 http://your_server_ip
。 你会看到一个页面,上面写着 Welcome to OpenResty! 并确认它已完全安装并工作。
您现在可以停止 OpenResty 服务器。
sudo /usr/local/openresty/bin/openresty -s quit
OpenResty 已安装,但您仍需要将 OpenResty 配置为在启动时运行,这样就不必手动启动服务器。
第 3 步 — 将 OpenResty 设置为服务
在这里,我们要将 OpenResty 设置为服务,以便它在启动时自动启动。 我们将使用 systemd
初始化服务来执行此操作。 您可以阅读 this systemd basics tutorial 了解更多信息,并阅读 this unit file tutorial 了解有关单元文件的详细信息。
首先使用 nano
或您喜欢的文本编辑器创建一个新的 systemd
文件。
sudo nano /etc/systemd/system/openresty.service
对于本教程,我们将从全新安装中复制默认的 Nginx systemd
文件并针对 OpenResty 进行修改。 完整的文件看起来像这样,应该粘贴到我们刚刚打开的文件中。 我们将遍历文件的每个部分来解释它在做什么。
/etc/systemd/system/openresty.service
# Stop dance for OpenResty # A modification of the Nginx systemd script # ======================= # # ExecStop sends SIGSTOP (graceful stop) to the Nginx process. # If, after 5s (--retry QUIT/5) OpenResty is still running, systemd takes control # and sends SIGTERM (fast shutdown) to the main process. # After another 5s (TimeoutStopSec=5), and if OpenResty is alive, systemd sends # SIGKILL to all the remaining processes in the process group (KillMode=mixed). # # Nginx signals reference doc: # http://nginx.org/en/docs/control.html # [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
在 [Unit]
部分:
After=network.target
使 OpenResty 在网络启动后启动,以便 OpenResty 可以绑定和监听端口。 这允许它从外部到达。
在 [Service]
部分:
Type=forking
告诉systemd
我们在ExecStart
中调用的进程将在后台启动服务,并且该进程将在完成后自行停止。PIDFile=/run/openresty.pid
告诉systemd
在哪里可以找到 OpenResty 启动时创建的 PID 文件。 这允许systemd
知道 OpenResty 是否仍在运行。ExecStartPre=/usr/local/openresty/bin/openresty -t -q -g 'daemon on; master_process on;'
调用 OpenResty 脚本而不启动它。-t
标志告诉 OpenResty 我们只希望它测试配置文件;-q
标志告诉它我们要抑制任何非错误输出;-g
标志设置全局指令daemon on; master_process on
告诉 OpenResty 我们希望它作为守护进程在后台启动。 我们将这个脚本作为ExecStartPre
执行,这样当配置文件无效时,systemd
就不会尝试启动 OpenResty,因为它会在这个命令上出错。ExecStart=/usr/local/openresty/bin/openresty -g 'daemon on; master_process on;'
实际上启动了 OpenReesty。 这与没有-t
标志的ExecStartPre
相同。- 当我们运行
systemctl reload openresty
时,ExecReload=/usr/local/openresty/bin/openresty -g 'daemon on; master_process on;' -s reload
告诉systemd
运行此命令。-s
标志告诉 OpenResty 重新加载其配置文件。 ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/openresty.pid
告诉systemd
在 OpenResty 停止时运行此命令。 它将SIGSTOP
发送到 PID 文件中列出的进程。 如果 5 秒后它还在运行,systemd
将通过以下两个选项进行控制。TimeoutStopSec=5
告诉systemd
我们希望进程在 5 秒内停止。 如果它没有停止,systemd
将强制尝试停止 OpenRest。KillMode=mixed
指定systemd
在 5 秒后仍未停止时应如何尝试停止 OpenResty。
在 [Install]
部分:
WantedBy=multi-user.target
告诉systemd
我们希望服务何时启动,如果它被配置为在启动时启动。multi-user.target
表示服务只有在多用户系统启动后才会启动,即 我们可以以不同的用户身份运行 OpenResty。
这就是 etc/systemd/system/openresty.service
文件的全部内容。 接下来,我们需要自定义 OpenResty Nginx 配置文件并启用服务。
首先打开配置文件。
sudo nano /usr/local/openresty/nginx/conf/nginx.conf
默认情况下,它将如下所示:
默认 /usr/local/openresty/nginx/conf/nginx.conf
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } . . .
删除 events {
行之前的所有内容,并将其替换为以下三行:
更新了 /usr/local/openresty/nginx/conf/nginx.conf
user www-data; worker_processes auto; pid /run/openresty.pid; events { worker_connections 1024; } . . .
该文件将确保我们以 www-data 用户身份运行,并且 systemd
可以识别 OpenResty 何时运行,因为 OpenResty 将创建 pid
行一旦开始。
保存并关闭文件。
接下来,创建日志目录。
sudo mkdir /var/log/openresty
重新加载 systemd
服务,以便它可以找到我们的文件。
sudo systemctl daemon-reload
现在,通过 systemd
启动 OpenResty。
sudo systemctl start openresty
您现在可以再次访问 http://your_server_ip
并看到与以前相同的网页。 不同的是,现在进程已经被systemd
启动了。
最后一步是启用服务,这将确保 OpenResty 在启动时启动。
sudo systemctl enable openresty
您可以在我们的 服务和单元教程 中了解有关管理 systemd
服务和单元的更多信息。
现在我们已经配置了服务,我们可以进一步配置 OpenResty,例如 登录到一个公共位置。
第 4 步 — 配置 OpenResty
为了配置 OpenResty,我们使用了默认的 Nginx 配置作为参考,因此它与您可能熟悉的大部分内容相匹配。
首先,再次打开 OpenResty 配置文件:
sudo nano /usr/local/openresty/nginx/conf/nginx.conf
这一次,我们将修改 http
块并将 http
块内的 server
块移动到一个新文件中以获得更好的结构。 首先,找到 http {
行,删除它之后的所有内容,除了最后一行对应的 }
。
当前 /usr/local/openresty/nginx/conf/nginx.conf
user www-data; worker_processes auto; pid /run/openresty.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; . . . }
然后,将以下内容复制到 http
块中,使您的整个文件看起来像这样。 我们将一次一个地检查更改。
/usr/local/openresty/nginx/conf/nginx.conf
user www-data; worker_processes auto; pid /run/openresty.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; access_log /var/log/openresty/access.log; error_log /var/log/openresty/error.log; gzip on; gzip_disable "msie6"; include ../sites/*; }
保存并关闭文件。
我们对默认文件所做的更改是:
- 取消注释
tcp_nopush on;
,它告诉 OpenResty 只发送完整的数据包。 这个选项在使用sendfile
选项时很有用,这将允许 OpenResty 优化将静态文件发送到客户端。 - 添加
tcp_nodelay on;
。 该选项会尽快尝试发送数据包,这可能看起来与上面的选项相反,但它是在不同的时间使用的。tcp_nodelay
仅在对 HTTP 请求使用keepalive
选项时使用,这是通过 Web 浏览器连接到 Web 服务器,这将避免每次请求时都启动 HTTP 连接的开销制作。 - 添加和修改
ssl_protocols
和ssl_prefer_server_ciphers
行。 这些选项配置 OpenResty 的 SSL 选项。 我们删除了易受 HTTPS 已知攻击(例如 POODLE 攻击)的旧协议。 - 添加
access_log
和error_log
行,用于配置 Web 服务器的日志。 我们将日志存储在我们在上一步中创建的/var/log/openresty
目录中。 - 取消注释
gzip on
并添加gzip_disable "msie6"
。 这些选项将配置 GZIP,它将压缩网页,以便传输更少的数据。 我们还添加了最后一个选项,因为 Internet Explorer 6(和更早版本)并不总是正确处理 GZIP 内容。 - 添加
include ../sites/*;
,它告诉 OpenResty 在/usr/local/openresty/nginx/sites
目录中寻找额外的配置文件,我们稍后会创建它。 - 删除所有
server
块,我们将在此步骤稍后将其重新定位到新文件。
接下来,创建我们在 include
行中指定的新 sites
目录。
sudo mkdir /usr/local/openresty/nginx/sites
创建 default
站点。
sudo nano /usr/local/openresty/nginx/sites/default.conf
在这个新文件中添加以下内容。 这是从 nginx.conf
中重新定位的原始服务器块,但有更多详细信息的内联注释。
/usr/local/openresty/nginx/sites/default.conf
server { # Listen on port 80. listen 80 default_server; listen [::]:80 default_server; # The document root. root /usr/local/openresty/nginx/html/default; # Add index.php if you are using PHP. index index.html index.htm; # The server name, which isn't relevant in this case, because we only have one. server_name _; # When we try to access this site... location / { # ... first attempt to serve request as file, then as a directory, # then fall back to displaying a 404. try_files $uri $uri/ =404; } # Redirect server error pages to the static page /50x.html. error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/openresty/nginx/html; } }
保存并关闭文件。
现在,为此站点创建一个新目录。
sudo mkdir /usr/local/openresty/nginx/html/default
然后将原来的 index.html
从原来的位置移动到新目录。
sudo mv /usr/local/openresty/nginx/html/index.html /usr/local/openresty/nginx/html/default
最后,重新启动 OpenResty 以使用这个新站点。
sudo systemctl restart openresty
您现在可以再次访问 http://your_server_ip
并看到与以前相同的网页。
现在 OpenResty 已经完全配置好了,我们可以试试 OpenResty 引入的一些 Nginx 默认不具备的功能。
第 5 步 — 使用 OpenResty Lua 模块
在本节中,我们将查看 OpenResty 添加的不同模块的组合,这些模块都存在以适应 Lua 脚本。 我们将在这一步中修改/usr/local/openresty/nginx/sites/default.conf
,所以先打开它。
sudo nano /usr/local/openresty/nginx/sites/default.conf
首先,我们来看看 content_by_lua_block
配置选项。 从下面的示例配置中复制 location
块并将其添加到 server
块中,在两个现有 location
块下方。
/usr/local/openresty/nginx/sites/default.conf content_by_lua_block 示例
server { . . . location /example { default_type 'text/plain'; content_by_lua_block { ngx.say('Hello, Sammy!') } } }
保存并关闭文件,然后重新加载配置。
sudo systemctl reload openresty
如果你现在访问 http://your_server_ip/example
,你会看到一个页面,上面写着 Hello, Sammy!。 让我们解释一下这是如何工作的。
content_by_lua_block
配置指令将其中的所有内容作为 Lua 代码执行。 在这里,我们使用 Lua 函数 ngx.say
将消息 Hello, Sammy! 打印到页面上。
再举一个例子,将 location /example
块的内容替换为:
/usr/local/openresty/nginx/sites/default.conf content_by_lua_file 示例
server { . . . location /example { default_type 'text/plain'; content_by_lua_file /usr/local/openresty/nginx/html/default/index.lua; } }
content_by_lua_file
从外部文件加载 Lua 内容,所以让我们创建上面指定的文件:/usr/local/openresty/nginx/html/default/index.lua
。
sudo nano /usr/local/openresty/nginx/html/default/index.lua
将以下内容添加到文件中,然后保存并关闭它。
/usr/local/openresty/nginx/html/default/index.lua
local name = ngx.var.arg_name or "Anonymous" ngx.say("Hello, ", name, "!")
这是一个简单的 Lua 片段,它读取 URL 中的查询参数 name
,并自定义问候消息。 如果未传递任何参数,则使用“匿名”代替。
重新加载配置。
sudo systemctl reload openresty
现在,在浏览器中访问 http://your_server_ip/example?name=Sammy
。 这将显示 Hello, Sammy!。 您可以更改 name
查询参数,或完全省略它。
Hello, Sammy!
您还可以更改 name
查询参数以显示任何其他名称。
警告: 不要将您正在加载的 Lua 文件放置在 Web 可访问的位置。 如果这样做,如果有人访问此文件,您的应用程序代码可能会被包含在内。 将文件放在文档根目录之外,例如将文档根目录更改为 /usr/local/openresty/nginx/html/default/public
并将 Lua 文件放在其上一个目录。
结论
在本文中,您将设置 OpenResty,这将使您能够在 Nginx 工作器中使用 Lua 脚本。 可以创建更复杂的 Lua 脚本。 例如,您还可以使用 Lua 脚本限制访问或使用 Lua 重写某些请求。 您可以在 lua-nginx-module 的 GitHub 页面 上找到文档。 甚至还有在 OpenResty 上使用 Lua 的完整 Web 框架,例如 Lapis。
如果想了解更多,可以访问OpenResty网站。 因为 OpenResty 只是一个扩展的 Nginx 安装,你也可以在 Nginx 服务器块教程 中学习如何设置服务器块,但请确保将教程中使用的路径替换为本教程中使用的路径.