控制 API§
Unit 的配置基于 JSON,可通过 RESTful 控制 API 访问,并完全可通过 HTTP 管理。控制 API 提供了一个根对象 (/),其中包含四个主要选项
对象 |
说明 |
---|---|
/certificates |
负责 SSL/TLS 证书管理。 |
/config |
用于常规 配置管理。 |
/control |
查询 应用程序重启。 |
/status |
查询 使用统计。 |
API 通过套接字公开,其类型和地址取决于 安装方法。其编译时设置可以在 启动时覆盖。为了保持一致性和 安全性,我们的示例使用 Unix 域套接字(除非另有说明)。示例查询使用 curl,并且 URI 以 https://127.0.0.1 为前缀,因为该实用程序需要(主机名与 Unit 本身无关),但你可以使用任何你喜欢的 HTTP 工具。例如,Visual Studio Code 用户可能会受益于此 第三方扩展。
No configuration files used
The control API is the single source of truth about Unit’s configuration. There are no configuration files that can or should be manipulated; this is a deliberate design choice made to avoid issues such as:
Undetected invalid states: Configuration files can be saved in an invalid state, and the issue won’t be seen until reload or startup. The control API avoids this by validating configuration changes on the fly.
Too broad or too narrow configuration file permissions: If a configuration file is inaccessible, it can’t be loaded; if it’s public, sensitive data may leak. The control API has a single manageable point of entry.
Unpredictable behavior: In a configuration file hierarchy, it’s easy to lose track and misconfigure something. With the control API, the entire configuration is a single, organized, and navigatable entity.
Replicating Unit states
Although Unit is fully dynamic, sometimes you just want to copy an existing setup without extra modification. Unit’s state directories are interchangeable as long as Unit version stays the same, so you can use a shortcut to replicate a Unit instance. Also, this works with the Docker images.
Warning
Unit’s state can change its structure between versions and must not be edited by external means.
On the machine where the reference Unit instance runs, find out where the state is stored:
$ unitd -h
--state DIRECTORY set state directory name
default: "/path/to/reference/unit/state"
Double-check that the state location isn’t overridden at startup:
$ ps ax | grep unitd
...
unit: main v1.32.1 [unitd --state /runtime/path/to/reference/unit/state ... ]
Repeat these commands on the second machine to see where the target instance stores its state.
Stop both Unit instances, for example:
# systemctl stop unit
Note
Stop and start commands may differ if Unit was installed from a non-official repo or built from source.
Copy the reference state directory to the target state directory by arbitrary means; make sure to include subdirectories and hidden files. Finally, restart both Unit instances:
# systemctl restart unit
If you run your Unit instances manually, --state can be used to set the state directory at startup.
After restart, the target instance picks up the configuration you’ve copied to the state directory.
OpenAPI 规范§
如需更正式地了解 Unit 的控制 API,请下载 OpenAPI 规范或尝试交互式 Docker
version
。首先,构建映像并运行容器$ docker build --tag=unit-openapi -f unit-openapi.Dockerfile . $ docker run -d -p 8765:8765 -p 8080:8080 unit-openapi接下来,在浏览器中打开 https://127.0.0.1:8765。
要在预先存在的 Unit 实例上使用此映像,请在页面上键入该实例 控制套接字 的地址和端口(现在仅支持 IP 套接字)
快速入门§
对于简要介绍,我们配置 Unit 来提供一个静态文件。假设您将其保存为 /www/data/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to NGINX Unit!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to NGINX Unit!</h1>
<p>If you see this page, the NGINX Unit web server is successfully
installed and working. Further configuration is required.
</p>
<p>For online documentation and support, please refer to
<a href="https://unit.nginxserver.cn/">unit.nginx.org</a>.<br/>
</p>
<p><em>Thank you for using NGINX Unit.</em></p>
</body>
</html>
现在,Unit 应该监听一个端口,该端口路由传入请求到一个share操作,该操作提供文件
{
"listeners": {
"127.0.0.1:8080": {
"pass": "routes"
}
},
"routes": [
{
"action": {
"share": "/www/data$uri"
}
}
]
}
要配置 Unit,请通过控制套接字将此代码段PUT到/config部分。在命令行中使用 JSON 可能很繁琐;相反,将其另存为snippet.json并上传
# curl -X PUT --data-binary @snippet.json --unix-socket \
/path/to/control.unit.sock https://127.0.0.1/config
{
"success": "Reconfiguration done."
}
要确认此操作有效,请查询侦听器。Unit 使用share目录中的index.html文件进行响应
$ curl -i 127.0.0.1:8080
HTTP/1.1 200 OK
Content-Type: text/html
Server: Unit/1.28.0
<!DOCTYPE html>
<html>
<head>
<title>Welcome to NGINX Unit!</title>
...
API 操作§
要解决控制 API 的部分,请通过 HTTP 查询控制套接字;API 请求的 URI 路径段必须是其JSON 对象成员的名称或其JSON 数组元素的索引。
API 支持以下 HTTP 方法
方法 |
操作 |
---|---|
GET |
将请求 URI 处的实体作为 HTTP 响应正文中的 JSON 值返回。 |
POST |
更新请求 URI 处的数组,追加来自 HTTP 请求正文的 JSON 值。 |
PUT |
替换请求 URI 处的实体,并在 HTTP 响应正文中返回状态消息。 |
DELETE |
删除请求 URI 处的实体,并在 HTTP 响应正文中返回状态消息。 |
在进行更改之前,Unit 会检查它在整个配置中产生的差异;如果没有差异,则不执行任何操作。因此,您无法通过重新上传其未更改的配置来重新启动应用程序(但有一种方法可以重新启动应用程序)。
Unit 以尽可能优雅的方式执行实际重新配置步骤:正在运行的任务自然过期,连接已正确关闭,进程平稳结束。
只要您提供正确的 JSON,就可以使用不同的 URI 执行任何类型的更新
# curl -X PUT -d '{ "pass": "applications/blogs" }' --unix-socket \
/path/to/control.unit.sock https://127.0.0.1/config/listeners/127.0.0.1:8300
# curl -X PUT -d '"applications/blogs"' --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/listeners/127.0.0.1:8300/pass
但是,第一个命令将替换整个侦听器,删除您可能配置的任何其他选项,而第二个命令仅替换pass值,并保持其他选项不变。
示例§
为了最大程度地减少错别字和工作量,请避免在命令中嵌入 JSON 有效负载;相反,请存储配置代码段以供审阅和重复使用。例如,将应用程序对象另存为 wiki.json
{
"type": "python",
"module": "wsgi",
"user": "www-wiki",
"group": "www-wiki",
"path": "/www/wiki/"
}
使用它来设置名为 wiki-prod 的应用程序
# curl -X PUT --data-binary @wiki.json \
--unix-socket /path/to/control.unit.sock https://127.0.0.1/config/applications/wiki-prod
再次使用它来设置名为 wiki-dev 的同一应用程序的开发版本
# curl -X PUT --data-binary @wiki.json \
--unix-socket /path/to/control.unit.sock https://127.0.0.1/config/applications/wiki-dev
将 wiki-dev 应用程序切换到另一个源代码目录
# curl -X PUT -d '"/www/wiki-dev/"' \
--unix-socket /path/to/control.unit.sock https://127.0.0.1/config/applications/wiki-dev/path
接下来,提升生产应用程序的进程计数以对其进行一些预热
# curl -X PUT -d '5' \
--unix-socket /path/to/control.unit.sock https://127.0.0.1/config/applications/wiki-prod/processes
为 wiki-prod 应用程序添加一个侦听器,以接受所有主机 IP 的请求
# curl -X PUT -d '{ "pass": "applications/wiki-prod" }' \
--unix-socket /path/to/control.unit.sock 'https://127.0.0.1/config/listeners/*:8400'
将 wiki-dev 应用程序插入侦听器以对其进行测试
# curl -X PUT -d '"applications/wiki-dev"' --unix-socket /path/to/control.unit.sock \
'https://127.0.0.1/config/listeners/*:8400/pass'
然后重新连接侦听器,向应用程序的开发版本添加基于 URI 的路由
$ cat << EOF > config.json
[
{
"match": {
"uri": "/dev/*"
},
"action": {
"pass": "applications/wiki-dev"
}
}
]
EOF
# curl -X PUT --data-binary @config.json --unix-socket \
/path/to/control.unit.sock https://127.0.0.1/config/routes
# curl -X PUT -d '"routes"' --unix-socket \
/path/to/control.unit.sock 'https://127.0.0.1/config/listeners/*:8400/pass'
接下来,使用其索引 (0) 更改 routes 数组中 wiki-dev 的 URI 前缀
# curl -X PUT -d '"/development/*"' --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/routes/0/match/uri
向生产应用程序追加一个路由:POST 始终添加到数组末尾,因此不需要索引
# curl -X POST -d '{"match": {"uri": "/production/*"}, \
"action": {"pass": "applications/wiki-prod"}}' \
--unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/routes/
否则,使用 PUT 和数组的最后一个索引 (在我们的示例中为 0) 加一,以在末尾添加新项目
# curl -X PUT -d '{"match": {"uri": "/production/*"}, \
"action": {"pass": "applications/wiki-prod"}}' \
--unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/routes/1/
获取完整的 /config 部分
# curl --unix-socket /path/to/control.unit.sock https://127.0.0.1/config/
{
"listeners": {
"*:8400": {
"pass": "routes"
}
},
"applications": {
"wiki-dev": {
"type": "python",
"module": "wsgi",
"user": "www-wiki",
"group": "www-wiki",
"path": "/www/wiki-dev/"
},
"wiki-prod": {
"type": "python",
"processes": 5,
"module": "wsgi",
"user": "www-wiki",
"group": "www-wiki",
"path": "/www/wiki/"
}
},
"routes": [
{
"match": {
"uri": "/development/*"
},
"action": {
"pass": "applications/wiki-dev"
}
},
{
"action": {
"pass": "applications/wiki-prod"
}
}
]
}
获取 wiki-dev 应用程序对象
# curl --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/applications/wiki-dev
{
"type": "python",
"module": "wsgi",
"user": "www-wiki",
"group": "www-wiki",
"path": "/www/wiki-dev/"
}
您可以将此类请求返回的 JSON 保存为 .json 文件以进行更新或审阅
# curl --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/ > config.json
删除 *:8400 上的侦听器
# curl -X DELETE --unix-socket /path/to/control.unit.sock \
'https://127.0.0.1/config/listeners/*:8400'
请注意,您无法删除其他对象依赖的对象,例如侦听器仍引用的路由
# curl -X DELETE --unix-socket /path/to/control.unit.sock \
https://127.0.0.1/config/routes
{
"error": "Invalid configuration.",
"detail": "Request \"pass\" points to invalid location \"routes\"."
}