簡介
微服務大潮席捲而來,NGINX 官方也不得不做出一些改變,Unit 專案應運而生,它是一個動態的網路應用伺服器,設計之初就支援執行多種程式語言,並且在執行過程中,可通過 API 動態配置已有應用的引數。
專案地址 https://github.com/nginx/unit
核心功能
- 可使用 RESTful JSON API 動態配置伺服器
- 可同時執行多語言及多版本的應用
- 動態語言的程式管理功能(開發中)
- TLS 支援(開發中)
- TCP, HTTP, HTTPS, HTTP/2 路由和代理(開發中)
支援的語言
- Python
- PHP
- Go
- JavaScript / Node.js (開發中)
- Java (開發中)
- Ruby (開發中)
使用包管理器安裝
目前只支援 CentOS 7.0 和 Ubuntu 16.04。
CentOS
- 建立 /etc/yum.repos.d/unit.repo,內容如下:
[unit] name=unit repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1
- 安裝
yum install unit
Ubuntu
- 下載 祕鑰,該祕鑰用於驗證 NGINX 源的簽名,執行
sudo apt-key add nginx_signing.key
- 在 /etc/apt/sources.list 增加如下內容:
deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx
- 安裝
apt-get update apt-get install unit
從原始碼編譯安裝
安裝依賴
- Ubuntu
apt-get install build-essential php-dev libphp-embed
- CentOS
yum install gcc make php-devel php-embedded
配置 PHP 模組,最終會生成名為 php.unit.so
的檔案
git clone https://github.com/nginx/unit
cd unit
./configure
./configure php
如果是自定義安裝的 PHP,需要用如下命令:
./configure php --module=<prefix> --config=<script-name> --lib-path=<pathname>
其中的引數含義如下:
- --module
設定 php 模組的檔名字首,最終生成的檔名為<prefix>.unit.so
- --config
php-config 指令碼所在的路徑 - --lib-path
PHP library 所在的路徑
以 PHP7.0 為例,命令如下:
./configure php --module=php70 \
--config=/usr/lib64/php7.0/php-config \
--lib-path=/usr/lib64/php7.0/lib64
得到如下輸出:
configuring PHP module
checking for PHP ... found
+ PHP version: 7.0.22-0ubuntu0.16.04.1
+ PHP SAPI: [apache2handler embed cgi cli fpm]
checking for PHP embed SAPI ... found
+ PHP module: php70.unit.so
編譯安裝
make all
make install
從 Docker 安裝
docker pull airycanon/nginx-unit-php
配置和執行
配置檔案
一個基礎的配置檔案必須包含以下兩部分:
-
應用
下面的示例描述了一個名為 blog 的 PHP 應用{ "applications": { "blog": { "type": "php", "workers": 20, "root": "/www/blogs/scripts", "index": "index.php" } } }
配置項 描述 type 應用的程式語言 workers workers 的數量 root 應用的根目錄 index 應用入口檔案 working_directory (可選) 應用的工作目錄 script(可選) 指令碼路徑,基於應用根目錄的相對路徑,訪問應用內的任意 URL 均會執行該指令碼 user(可選) 執行程式的使用者,預設為 nobody group(可選) 使用者所在的使用者組,預設為 user 的使用者組 - 監聽器
監聽器指定了 IP 和 埠以及繫結的應用,下面的示例中,埠 8300 的請求全部會被髮送至 blogs 這個應用:{ "listeners": { "*:8300": { "application": "blog" } }, ... }
建立應用
這裡為了簡化步驟,採用了 Docker
的方式執行。
-
首先建立兩個目錄
applications
run
作為容器的 Volume 掛載mkdir applications run docker run -v `pwd`/applications:/applications -v `pwd`/run:/var/run:rw -p 8300:8300 -d airycanon/nginx-unit-php
-
建立一個配置檔案
json/config.json
,內容如下:{ "listeners": { "*:8300": { "application": "blog" } }, "applications": { "blog": { "type": "php", "workers": 20, "root": "/applications/blog", "index": "index.php" } } }
-
建立一個
applications/blog/index.php
,內容如下<?php phpinfo(); ?>
- 預設情況下,Unit 通過
Unix domain socket
檔案unit.control.sock
提供 API,通過如下命令建立應用:curl -X PUT -d @./json/config.json --unix-socket ./run/control.unit.sock http://localhost/
訪問 http://localhost:8300 可以看到 phpinfo 的頁面
檢視應用配置
-
檢視所有應用的配置:
curl --unix-socket ./run/control.unit.sock http://localhost/
{ "applications": { "blogs": { "type": "php", "user": "nobody", "group": "nobody", "workers": 20, "root": "/applications/blog", "index": "index.php" } }, "listeners": { "*:8300": { "application": "blog" }, } }
- 檢視某個應用的配置:
curl --unix-socket ./run/control.unit.sock http://localhost/applications/blog
{ "type": "php", "user": "nobody", "group": "nobody", "workers": 20, "root": "/applications/blog", "index": "index.php" }
修改應用
-
修改 *:8300 監聽繫結的應用:
curl -X PUT -d '"blog-dev"' --unix-socket ./run/control.unit.sock http://localhost/listeners/*:8300/application
{ "success": "Reconfiguration done." }
- 修改應用的根目錄:
curl -X PUT -d '"/applications/blog-dev"' --unix-socket ./run/control.unit.sock http://localhost/applications/blog/root
{ "success": "Reconfiguration done." }
刪除應用
-
刪除對 *:8300 埠的監聽:
curl -X DELETE --unix-socket ./run/control.unit.sock http://localhost/listeners/*:8300
{ "success": "Reconfiguration done." }
- 刪除應用:
curl -X DELETE --unix-socket ./run/control.unit.sock http://localhost/applications/blog
{ "success": "Reconfiguration done." }
與 NGINX 一起使用
使用 NGINX 作為代理
先宣告 upstream
upstream unit_backend {
server 127.0.0.1:8300;
}
-
示例 1
server { location / { root /var/www/static-data; } location ~ \.php$ { proxy_pass http://unit_backend; proxy_set_header Host $host; } }
-
示例 2
server { location /static { root /var/www/files; } location / { proxy_pass http://unit_backend; proxy_set_header Host $host; } }
設定 Unix domain socket
的 API 可以被遠端訪問
由於該 API 可以動態修改應用資訊,請務必增加安全認證
server {
# Configure SSL encryption
server 443 ssl;
ssl_certificate /path/to/ssl/cert.pem;
ssl_certificate_key /path/to/ssl/cert.key;
# Configure SSL client certificate validation
ssl_client_certificate /path/to/ca.pem;
ssl_verify_client on;
# Configure network ACLs
#allow 1.2.3.4; # Uncomment and change to the IP addresses and networks
# of the administrative systems.
deny all;
# Configure HTTP Basic authentication
auth_basic on;
auth_basic_user_file /path/to/htpasswd.txt;
location / {
proxy_pass http://unix:/var/run/control.unit.sock
}
}
本文同時釋出在我的 個人部落格