在 CentOS 7 上运行 Nginx Unit

大家好,
我是Mandai,Wild团队负责开发工作的成员。

大家都很喜欢不久前发布的新 Nginx 系列产品“Nginx Unit”。

我做了一些研究,了解如何使用 Nginx Unit。

 

目录

 

什么是 Nginx Unit?

Nginx Unit 是一个中间件,它充当 Web 应用程序服务器,就像 Nginx 一样。

Nginx Unit 的特点如下:

  • 动态修改配置文件(无需重启)
  • 单个 Nginx 服务器可以运行多种编程语言的服务

据说有这样一个地方。

这次,我想实际安装一下,亲身感受一下它的使用体验。

 

如何安装

对于 CentOS 系统,可以通过 yum 安装,非常简单。

基本上官方文档按照

首先,注册 Nginx Unit 仓库。

sudo vi /etc/yum.repos.d/unit.repo # 粘贴以下内容 [unit] name=unit repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1

 

至此,初步设置完成。
接下来,我们将运行 yum 命令。

yum install unit 已加载插件:fastestmirror、langpacks 从缓存的主机文件加载镜像速度 * base: ftp.riken.jp * epel: mirror.dmmlabs.jp * extras: ftp.riken.jp * nux-dextop: li.nux.ro * remi-safe: mirror.bebout.net * updates: ftp.riken.jp 正在解析依赖关系 --> 正在运行事务检查 ---> 正在安装软件包 unit.x86_64 0:0.1-1.el7.ngx --> 正在处理依赖关系:软件包 unit-0.1-1.el7.ngx.x86_64 的 libphp5-5.4.so()(64bit) --> 正在运行事务检查 ---> 正在安装软件包 php-embedded.x86_64 0:5.4.16-42.el7 --> 正在处理依赖关系:php-common(x86-64) =正在为软件包 php-embedded-5.4.16-42.el7.x86_64 安装 5.4.16-42.el7 版本 --> 正在运行事务检查 ---> 正在安装软件包 php-common.x86_64 0:5.4.16-42.el7 --> 正在处理依赖项:软件包 php-common-5.4.16-42.el7.x86_64 的 libzip.so.2()(64bit) --> 正在运行事务检查 ---> 正在安装软件包 libzip.x86_64 0:0.10.1-8.el7 --> 依赖关系解析完成。依赖关系已解析 ~ 省略 ~ 感谢您安装 NGINX Unit!您可能需要加载演示配置并检查几个应用程序: # service unitd start # service unitd restoreconfig /usr/share/doc/unit/examples/example.config # curl http://localhost:8300/ # curl http://localhost:8400/ 在线文档可在 http://unit.nginx.org/ 获取 ---------------------------------------------------------------------- 测试:php-embedded-5.4.16-42.el7.x86_64 1/4 测试:libzip-0.10.1-8.el7.x86_64 2/4 测试:php-common-5.4.16-42.el7.x86_64 3/4 测试:unit-0.1-1.el7.ngx.x86_64 4/4 已安装:unit.x86_64 0:0.1-1.el7.ngx 已安装依赖项:libzip.x86_64 0:0.10.1-8.el7 php-common.x86_64 0:5.4.16-42.el7 php-embedded.x86_64 0:5.4.16-42.el7 完成!

 

令人费解的是,PHP(而且还是版本 5!)为何会在依赖项检查中被标记出来(大概是因为它从基础仓库拉取 PHP 来提供执行环境)。
如果您已经安装了 PHP,或者想在 PHP7 环境中使用它,那么从源代码安装似乎是更好的选择。

对于源码安装,您需要为运行环境准备必要的库并进行编译。
特别是如果您使用的是 PHP7,通过 yum 安装可能会比较困难,因此以下请尝试按照

 

首先,启动服务

在刚才看到的 yum 安装界面末尾,有一个启动服务的命令,所以我先尝试运行它。
虽然它需要 CentOS 7,但它使用的是 `service` 命令,所以我将向您展示我最近学到的 `systemctl` 命令!

# 首先,启动服务 sudo systemctl start unitd # 恢复配置文件 $ service unitd restoreconfig /usr/share/doc/unit/examples/example.config 正在从 /usr/share/doc/unit/examples/example.config 恢复配置... { "success": "重新配置完成。" }

 

对于第二个命令,我不知道如何将其转换为 systemctl 命令,所以我直接使用了 service 命令。

顺便一提,如果将第一个命令作为服务命令运行,结果将如下所示。

sudo service unitd start 重定向到 /bin/systemctl start unitd.service

 

程序确实执行成功,但一直提示是用 systemctl 命令执行的。
然而,当我用 restoreconfig 命令运行时,并没有出现这类警告,所以我怀疑使用 service 命令是否是正确的方法。

此时,它应该运行正常,因此您可能会想用 curl 命令验证其运行情况……但关键在于:对于 Nginx,上述命令的执行顺序是相反的。
更新 Nginx 的配置文件后,总是需要重启服务,这不可避免地使得在服务运行时更改配置变得困难。这
一点很容易被忽略,但正是在这里,您可以初步体会到 Nginx Unit 的优势。

现在请再次尝试访问网络服务器。

$ curl http://localhost:8300/ [email protected]   $ curl http://localhost:8400/ 2017-10-17 02:11:15 AM ENV Variables: LANG ja_JP.utf8 PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin UNITD_OPTIONS --log /var/log/unitd.log --pid /run/unitd.pid

 

8300 端口似乎运行正常,像一个普通的 Web 服务器,phpinfo() 函数可以执行。8400
端口目前用途不明,但似乎在显示执行环境的设置。我们
稍后会探究这个端口的用途。

安装似乎很顺利,接下来我们将检查设置。

 

检查 Nginx 单元配置

目前看来,唯一像 Nginx Unit 配置文件的文件是 /usr/share/doc/unit/examples/example.config,所以我们来看看它。

less /usr/share/doc/unit/examples/example.config { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }

 

我打开文件后发现它是一个JSON文件。JSON
文件使配置结构易于理解。

前面提到的“http://localhost:8400”实际上是 Python 程序的备用 URL。

根据文档,似乎可以通过套接字通信来检查设置。
它看起来大概是这样的。

curl --unix-socket /path/to/socket http://localhost/

 

但是,要做到这一点,我们需要知道套接字文件的位置,所以我们将从进程活动的角度来看待这个问题。

首先,使用 ps 命令识别 Nginx Unit 进程。

ps auxwwwf | grep [u]nit root 5821 0.0 0.0 18256 636 ? Ss 00:21 0:00 unit: main [/usr/sbin/unitd --log /var/log/unitd.log --pid /run/unitd.pid] nobody 5824 0.0 0.0 18256 680 ? S 00:21 0:00 \_ unit: controller nobody 5825 0.0 0.0 18256 680 ? S 00:21 0:00 \_ unit: router

 

Nginx 单元似乎运行着三个进程:守护进程、控制器和路由器。
根据配置的不同,进程数可能会增加或减少,但这是当前的设置。

接下来,使用 lsof 命令检查进程 5821 正在保存的文件。

lsof -p 5821 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME unitd 5821 root cwd DIR 253,0 4096 2 / unitd 5821 root rtd DIR 253,0 4096 2 / unitd 5821 root txt REG 253,0 397232 806046 /usr/sbin/unitd unitd 5821 root mem REG 253,0 37352 805753 /usr/lib64/libnss_sss.so.2 unitd 5821 root mem REG 253,0 62184 787847 /usr/lib64/libnss_files-2.17.so unitd 5821 root mem REG 253,0 2118128 787829 /usr/lib64/libc-2.17.so unitd 5821 root mem REG 253,0 143944 787855 /usr/lib64/libpthread-2.17.so unitd 5821 root mem REG 253,0 19776 787835 /usr/lib64/libdl-2.17.so unitd 5821 root mem REG 253,0 44448 787859 /usr/lib64/librt-2.17.so unitd 5821 root mem REG 253,0 1141928 787837 /usr/lib64/libm-2.17.so unitd 5821 root mem REG 253,0 155464 806682 /usr/lib64/ld-2.17.so unitd 5821 root 0u CHR 1,3 0t0 1028 /dev/null unitd 5821 root 1u CHR 1,3 0t0 1028 /dev/null unitd 5821 root 2w REG 253,0 258231 136119 /var/log/unitd.log unitd 5821 root 3u a_inode 0,9 0 5832 [eventpoll] unitd 5821 root 4u a_inode 0,9 0 5832 [signalfd] unitd 5821 root 5u a_inode 0,9 0 5832 [eventfd] unitd 5821 root 6u unix 0xffff8800783ba400 0t0 48362 /var/run/control.unit.sock # <- 此单元 5821 root 7w REG 253,0 258231 136119 /var/log/unitd.log unitd 5821 root 8u unix 0xffff880023ebb400 0t0 49423 socket unitd 5821 root 9u unix 0xffff880023ebb800 0t0 49424 socket unitd 5821 root 12u unix 0xffff8800b1954800 0t0 49428 socket unitd 5821 root 13u unix 0xffff880023eb9c00 0t0 49430 插座

 

看起来“/var/run/control.unit.sock”是套接字文件,因此检查设置的命令如下。

curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }

 

使用 curl 命令检查 Web 服务器设置感觉很新颖,但它返回的内容与“/usr/share/doc/unit/examples/example.config”相同。
这意味着测试配置文件已成功加载。

接下来,我想更改设置。

 

更改 Nginx 单元设置

官方文档查看
文档中是这样写的:

# 示例:创建完整配置 curl -X PUT -d @/path/to/start.json \ --unix-socket ./control.unit.sock http://localhost/ # 示例:创建应用程序对象 curl -X PUT -d @/path/to/wiki.json \ --unix-socket ./control.unit.sock http://localhost/applications/wiki

 

我很容易就理解了如何应用第一个 JSON 文件,但第二个设置方法简直是噩梦。
它允许只将 JSON 应用于部分代码,但要用 URL 指定应用到哪一部分……!!

我还想测试一下读取我自己创建的JSON文件。
我已经准备了一个简单的JSON文件,如下所示。

{
"type": "php",
"user": "nobody",
"workers": 4,
"root": "/var/www/html",
"index": "index.php"
}

 

这是一个简单的设置,可以将文档根目录设为常用的“/var/www/html”目录,但它能正常工作吗?
请将此文件保存为“/home/hogehoge/test-php.json”。

让我们尝试使用 curl 命令将此请求发送到 Nginx Unit!
将其直接添加到 applications 目录下。

curl -X PUT -d @/home/hogehoge/test-php.json --unix-socket /var/run/control.unit.sock http://localhost/applications/test { "success": "重新配置完成。" }

 

注册似乎成功了。
我们再检查一下当前的设置。

curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }

 

添加成功了。
现在,我想用 curl 命令检查一下它是否正常工作……但是如果监听器没有注册,路由就无法工作,所以我还要添加路由 JSON 文件。

{
“应用程序”:“测试”
}

 

我们将使用 curl 以与之前相同的方式注册上述 JSON。

curl -X PUT -d @/home/hogehoge/test-php-listener.json --unix-socket /var/run/control.unit.sock http://localhost/listeners/*:8301 { "success": "重新配置完成。" }

 

最后一个 URL 比较特殊,但严格来说它并不是一个 URL,所以我们不必过于担心。
如果返回成功,我们将检查整个配置。

curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" }, "*:8301": { "application": "test" } } }

 

设置似乎已正确应用。
使用 curl 命令或在浏览器中检查
(此文档根目录下仍有使用 fuelPHP 开发的内容,但没有出现任何问题。)

 

删除 Nginx 单元配置

进行更改时,您发送 curl HTTP 方法 PUT,因此删除时,您自然会使用 DELETE 方法。

即使不看官方文档,你大概也能猜到答案,但为了确保万无一失,我们还是再确认一下。
使用 curl 删除文件的命令如下:

curl -X DELETE --unix-socket ./control.unit.sock \ 'http://localhost/listeners/*:8400'

 

我们来尝试删除之前添加的监听器设置。

curl -X DELETE --unix-socket /var/run/control.unit.sock http://localhost/listeners/*:8301 { "success": "重新配置完成。" }

 

是的,似乎已经成功删除了。

这部分很简单。

顺便一提,由于输入和输出都是 JSON 格式,所以保存设置非常容易。

# 将 curl 的结果写入文件 curl --unix-socket /var/run/control.unit.sock http://localhost/ > /path/to/unitd.conf.json # 检查写入是否可行 cat /path/to/unitd.conf.json { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } } # 重启 Nginx Unit systemctl restart unitd # 检查配置,未输入任何内容 curl --unix-socket /var/run/control.unit.sock http://localhost/ { "listeners": {}, "applications": {} } # 将之前输出的 JSON 数据输入到文件中 curl -X PUT -d @/root/unitd.conf.json --unix-socket /var/run/control.unit.sock http://localhost { "success": "重新配置完成。" } # 检查设置是否生效 curl --unix-socket /var/run/control.unit.sock http://localhost/ { "applications": { "example_php": { "type": "php", "user": "nobody", "workers": 2, "root": "/usr/share/doc/unit/examples/php-app", "index": "index.php" }, "example_python": { "type": "python", "user": "nobody", "workers": 2, "path": "/usr/share/doc/unit/examples/python-app", "module": "wsgi" }, "example_go": { "type": "go", "user": "nobody", "executable": "/tmp/go-app" }, "test": { "type": "php", "user": "nobody", "workers": 4, "root": "/var/www/html", "index": "index.php" } }, "listeners": { "*:8300": { "application": "example_php" }, "*:8400": { "application": "example_python" }, "*:8500": { "application": "example_go" } } }

 

成功了!

 

概括

你觉得这款前景看好的新工具 Nginx Unit 怎么样?
官方文档甚至描述了一种组合方案:Nginx 作为反向代理,请求通过套接字通信路由到 Nginx Unit。虽然将其配置重写为独立运行模式有点容易,而且启动时设置的应用方式也存在一些问题,但我认为它很好地弥补了 Nginx 灵活性不足的缺陷。

版本号是0.1。
当然,这是个测试版。
我很期待它未来会如何改进。

 
就这样。

如果您觉得这篇文章对您有帮助,请点个“赞”!
1
加载中...
1票,平均分:1.00/11
2,012
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

万代洋一

我的主要工作是开发社交游戏的Web API,但幸运的是,我也有机会参与其他各种任务,包括市场营销。
我在Beyond中的图像版权采用CC0协议。