Ngnix 是一款轻量级、高性能的 Web 应用服务器软件,同时也是一款代理服务器软件。它可以作为反向代理服务器软件,也可以作为电子邮件(IMAP/POP)代理服务软件。
作为服务器软件领域的佼佼者,Ngnix 真正体现了“小身体,大能量”的特色。软件本身小巧精致,配置和使用简单,但功能非常强大。其典型功能特点有,
- 高性能 Web 服务器
- 官方数据表明能支持高达 50000 个并发数
- 反向代理服务器
- 负载均衡
- 动静结合
在网络应用架构中,Nginx 使用非常广泛,具有重要的地位和作用。
Nginx 安装部署
需要安装 Ngnix 主程序和相关的配套支撑库。
手动编译需要源码,或者安装后缀为
-dev
的库
- Nginx 主程序
- 可直接用软件仓库的版本,可以手动编译安装。
- 官网网站:Nginx.org
- 可执行程序文件:nginx(bin 或 sbin 中)
- PCRE 库
- PCRE (Perl Compatible Regular Expressions) 是一个 Perl 库,包括 Perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式
- 库名称:libpcre3、libpcre3-dev (Ubuntu 18.04)
- zlib 库
- zlib 库提供了很多种压缩和解压缩的方式,nginx 使用 zlib 对 http 包的内容进行 gzip
- 库名称:zlib1g-dev (Ubuntu 18.04)
- OpenSSL 库
- OpenSSL 是一个强大的安全套接字层密码库。囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。Nginx 不仅支持 http 协议,还支持 https(即在 ssl 协议上传输 http),需要安装 OpenSSL 库。
- 库名称:openssl(Ubuntu 18.04)
Nginx 基本指令
使用可执行文件 nginx 启动服务。
./nginx
启动后,可以通过 -s
参数对 nginx 进行控制。
nginx -s signal
注:-s 参数表明采用向 Nginx 发送信号的方式
指令 | 备注 |
---|---|
nginx -s quit | 优雅停止。此方式是待 nginx 进程处理任务完毕进行停止 |
nginx -s stop | 强制停止。此方式先查出 nginx 进程 id,再使用 kill 命令强制杀掉进程 |
nginx -s reload | 不中断当前连接的情况下,重新加载更新后配置。类似于 “热更新”。 使用最多的指令,尤其是运行中进行配置更改 |
ngnix -s reopen | 重新打开 log 文件 |
nginx -t | nginx 不运行,仅仅对配置文件进行测试。 对 nginx 的配置文件修改后,常用此命令对修改后配置文件进行语法检查。 |
Nginx 的基本设计
虚拟主机
虚拟主机,就是把一台物理服务器划分成多个 “虚拟” 的服务器,这样一台物理服务器就可以当做多个服务器来使用,从而可以配置多个网站。Nginx 提供虚拟主机的功能,就是为了让用户不需要安装多个 Nginx,就可以运行多个域名不同的网站。
(典型的用一个物理实体达到实现多个不同的逻辑实体的效果,计算机中的常见设计)
每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的 Intemet 服务器功能(WWW、FTP、Email等),同一台主机上的虚拟主机之间是完全独立的。从网站访问者来看,每一台虚拟主机和一台独立的主机完全一样。
Nginx 支持虚拟主机,浏览器等客户端并不知道,所以通过几个不同的虚拟主机 url 地址,都指向 Nginx 所在的 ip 地址,都能到达 Nginx 环境,只不过针对不同的 url,Ngnix 的应对处理的逻辑不同。
实现上,Nginx 的虚拟主机就是通过主配置文件 nginx.conf 中 server 节点指定的,一个 server 标签就是一个虚拟主机。想要设置多个虚拟主机,配置多个 server 节点即可。
Nginx 配置文件的基本结构
Nginx 所有功能都体现在配置文件里。
ngnix.conf 是 Nginx 的中心配置文件,文件主要由三个大的部分组成:全局块、events 块、http 块。采用了一种“递进式”的结构布局。
全局块
全局块配置影响 nginx 服务器整体运行的配置指令。主要设置包括,
- 运行 nginx 服务器的用户或用户组;
- 允许生成的 worker process 数量;
- 进程 pid 的存放路径;
- 配置文件的引用,重点是服务器整体功能模块的配置
- 如
/etc/nginx/modules-enabled/*.conf
- 如
events 块
events 块配置影响 nginx 服务器与用户的网络连接。
http 块(包含多个 server 块)
http 块设置 Web 服务器 http 通信的核心内容,是 nginx 服务器中配置最频繁的部分。又进一步可细分为 “http 全局块” 和 “server 块(虚拟主机块)”。
(1) http 全局块
“http 全局块” 针对 http 的全局参数需求设计,主要设置包括,
- 文件引入
- MIME-TYPE类型
- 日志定义
- 连接超时时间
- ……
(2) server 块
“server 块” 主要针对“虚拟主机”的概念设计。
“虚拟主机”是一种概念上的主机,从用户角度看,一台“虚拟主机”就和一台独立硬件的主机完全一样。
http 块可以包括多个 server 块,每个 server 块就相当于一个虚拟主机。如此,每个 http 块可以包括多个“虚拟主机”的设置。
每个 server 块又进一步可细分为 “全局 server 块” 和多个 “location 块”。
- 全局 server 块对一个“虚拟主机”的整体进行设置,核心参数如“监听端口”、“主机名”、“主机的根目录”等
- location 块是客户端访问该“虚拟主机”时,对该“虚拟主机”的访问路由设置。客户端访问一个 “虚拟主机” 的不同路径时,可设置对应不同的处理
Ngnix 配置文件的基础参数与场景设置
配置文件实现
Nginx 的主配置文件为 nginx.conf
,通常位于系统配置目录(如 /etc/nginx/
)或 Nginx 的安装目录下(通过特定平台安装),典型的 nginx.conf
内容如下,
#################################################
###### 全局块 ######
#################################################
####################
# 设置 nginx 的 worker process 进程执行的用户
####################
user www-data;
####################
# 设置 nginx 中并发处理进程 worker process 的数量
# 这个设置一般与 CPU 内核数量相匹配,
# 每个用于 nginx 的内核分配一个 worker
####################
worker_processes 2;
####################
# 设置 nginx 的 pid
####################
pid /run/nginx.pid;
#################################################
###### event 块 ######
#################################################
events {
####################
# 每一个 worker 进程允许的最大连接数
# "worker 的数量 X 每个 worker 的连接数"决定了 nginx 的并发性能
####################
worker_connections 768;
} ## events 块设置结束
#################################################
###### http 块 ######
#################################################
http {
####################
# 进行文件传输,打开后文件传输性能提升
####################
sendfile on;
####################
# 当数据包累计到一定大小后,再发送,提升发送效率;
# 与 sendfile 合用
####################
tcp_nopush on;
####################
# 设置服务器传输文件的 mime 类型以及默认类型
####################
include /etc/nginx/mime.types;
default_type application/octet-stream;
####################
# 日志设置
####################
###### 用户对服务器的访问请求记录
access_log /var/log/nginx/access.log;
###### 设置 error 日志的存储位置
error_log /var/log/nginx/error.log;
###### 设置 error 日志的存储位置,以及存储的日志级别
###### 共分为 debug info notice warn error crit(ical) 等级别
# error_log /var/log/nginx/error.log info;
####################
# Gzip 压缩设置
####################
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
####################
# 虚拟主机设置 (Virtual Host Configs)
# 一个 server 块,一个"虚拟主机"
####################
###### 一个典型 server 块设置
server {
#####################
设置监听端口。本机所有的 ip 上都监听 80 端口;
如果只想监听某个端口,可以写为 192.168.1.202:80;
这样的话,只监听 192.168.1.202 上的 80 口
#####################
listen 80;
###### 设置服务器域名
server_name localhost domainname1 domainname2;
###### 站点根目录(程序目录)
root /var/www/html;
###### 索引文件
index index.html index.htm
location / {
root html;
index index.html index.htm
}
error_page 500 502 503 504 /50x.html;
location /50x.html {
root html;
}
} ## 一个 server 块设置结束
####################
优化配置
将 server 块放入单独的“碎片”配置文件中引入
方便多个 server 的设置,每一个 server 对应一个单独的“碎片”
####################
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
} ## http 块设置结束
Nginx 的功能都通过配置文件来体现,使用单一配置文件即可完成所有功能的配置。如果是针对功能简单的 Nginx 主机,使用单一配置文件清晰明了,但是,如果针对复杂的 Nginx 主机配置,尤其是需配置多种功能、多个虚拟主机的情况,使用单一文件也致使配置文件复杂冗长,查找和变更相关配置开关效率较低,为此,Nignx 的功能配置充分体现了 Linux 的平台文化,也采用了 “碎片化” 的设计。
在 Nginx 的配置目录中,设计多种不同的目录,存放不同的 “配置碎片”,通过在主配置文件中引入 “碎片配置” 灵活添加或删除对应的配置信息设置。
例如,在默认的配置安装目录 /etc/nginx/
中,设计了 3 个 “碎片” 文件夹 conf.d
、sites-enabled
、sites-available
。conf.d
一般存放通用设置的 “碎片配置”,sites-enabled
和 sites-available
一般存放虚拟主机的 “碎片配置”。主配置文件通过 include /etc/nginx/conf.d/*.conf;
、include /etc/nginx/sites-enabled/*;
指令将 “碎片配置” 添加到主配置文件中。其中,sites-available
文件夹往往用于存放备选虚拟主机配置的全集,而 sites-enabled
则存放实际发生作用的虚拟主机,通过在 sites-enabled
中设置到 sites-available
的软链接,可方便将备选的虚拟主机引入实际运行。如,
default -> /etc/nginx/sites-available/wordpress.conf
配置虚拟主机(vhost)
虚拟主机(vhost)的最大特点,就是一个真实的物理主机上,可以部属多台不同的虚拟主机。一个网络访问请求,到底应该由哪台虚拟主机来响应?Nginx 解决这个问题的办法是将http 访问请求(request)中的字段与 Nginx 中各个 server 块设置的字段进行匹配。请求中目标 ”IP : 端口”、“域名” 与虚拟主机 server 中对应字段匹配的结果,决定 Nginx 中哪台虚拟主机来 response。
http 请求 request 中的字段 | Ngnix 中 server 设置 |
---|---|
IP : port | listen |
host | server_namne |
虚拟主机的常见配置方法也围绕这两个关键要素展开。
配置方式 | 说明 |
---|---|
基于域名的虚拟主机 | 不同的域名、相同的IP。此方式应用最广泛。 |
基于IP地址的虚拟主机 | 不同的域名、不同的IP。需要在 Nginx 服务器上加网络接口 ,应用的不广泛 |
基于域名的 Nginx 虚拟主机
这类虚拟主机的特点是“IP 一致,域名不同”。
server {
listen 80;
server_name example.org www.example.org;
...
}
server {
listen 80;
server_name example.net www.example.net;
...
}
server {
listen 80;
server_name example.com www.example.com;
...
}
请求匹配规则:
接到一个请求后,Nginx 首先选定由哪一个虚拟主机来处理请求,如上面 3 个虚拟主机都监听在*:80 端口,则 Nginx 仅仅检查请求的“Host”字段以决定该请求应由哪个虚拟主机来处理。
如果 Host 字段没有匹配任意一个虚拟主机,或者请求中根本没有包含 Host 字段,那 nginx 会将请求分发到定义在此端口上的默认虚拟主机。可以显式地设置某个主机为默认虚拟主机,即在 “listen” 指令中设置 “default_server” 参数。示例如下,
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
基于 IP 的域名设置
域名本质是一个字符串,如果没有申请特定的域名,也可以使用 IP 字符串作为域名。
server {
listen 80;
server_name 192.168.16.162;
...
}
这里,192.168.16.162 作为虚拟主机的域名。
针对 frp 中 tcp 转发的设置
frp 中,如果使用 tcp 代理的方式访问内网 nginx 服务,其转发的 http request 的 host 字段采用的 frp server 的 ip:port,如 185.98.117.191 : 26518,此时内网 nginx 服务器的 server_name 需与 frp 转发 host 一致,方能顺利穿透。
server {
listen 80;
server_name 192.168.16.162 185.98.117.191;
...
}
上述例子中,192.168.16.162 是内网虚拟主机域名,185.98.117.191 是 frp server 的域名。内网 nginx 服务器处理 frp client 转发 http request 的 host 字段时,会忽略 port 部分(即 26518),直接处理 ip 部分(即 185.98.117.191)。
基于域名和IP混合的虚拟主机
这类虚拟主机的特点是“IP 不同,域名不同”。配置这类虚拟主机,需要物理主机有多个不同网络接口,每个网络接口配置不同的 IP 地址。
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80;
server_name example.com www.example.com;
...
}
请求匹配规则:
接到一个请求后,
– Nginx 首先做 listen 匹配。测试请求的 IP 地址和端口是否匹配某个 server 配置块中的 listen 配置。
– 接着做 server_name 匹配。Nginx 继续测试请求的 Host 字段是否匹配这个 server 块中的某个 server_name 的值。如果主机名没有找到,Nginx 将把这个请求交给默认虚拟主机处理。
server_name 设置方式
设置方式 | 示例 |
---|---|
准确 server_name 匹配 | server { listen 80; server_name domain.com www.domain.com; … } |
以*通配符开始 | server { listen 80; server_name *.domain.com; … } |
以*通配符结束 | server { listen 80; server_name www.*; … } |
正则表达式 | server { listen 80; server_name ~^(?.+).domain.com$; … } |
用户认证参数设置
nginx 提供 web 用户认证功能。可以通过设置认证机制,让 web 页面得到受控访问。
nginx 中用户认证功能由 ngx_http_auth_basic_module 模块实现,该模块也是 nginx 默认编译的常规模块。
参数 | 说明 | 作用域 |
---|---|---|
auth_basic | 作为 realm 使用,响应报文中使用 | http 块, server 块, location 块, limit_except |
auth_basic_user_file | 用户认证文件 | http 块, server 块, location 块, limit_except |
认证模块的配置文件示例如下,
server {
listen 8081;
server_name jiat.com;
auth_basic "User auth";
auth_basic_user_file /etc/nginx/sites-available/passwd;
location / {
root /var/www/html/authdir;
index index.html;
}
}
创建认证使用的用户名和密码,如使用 htpasswd 工具,
htpasswd -c /etc/nginx/sites-availables/passwd username
New password: 输入密码
Re-type new password: 再次输入密码
WebDAV 参数设置
设计缘起
WWW 推出后发展迅速,但其流行的主要特征是作为一个信息发布的媒介,即仅仅是一个“只读”的媒介。随着其使用愈加广泛,对 Web 的期望也愈加水涨船高,除了一个“可读”的媒介外,让 Web 进一步扩展,成为一个“可写、可编辑”媒介的需求也很迫切,人们期望在网络上利用 Web 实现“分布式编辑(创作)”,在这样的背景下,W3C 联盟专门成立了另一个 IETF 工作组对上述需求进行研究,最终以 RFC 4918 的形式发布了 WebDAV。
Berner-Lee 在设计第一个 Web 浏览器 WorldWideWeb 的时候,实际上可以同时查看和编辑网页;但是,随着 Web 的发展,其逐步演变成一个“只读”的媒体。
WebDAV 概述
WebDAV,全名 Web-based Distributed Authoring and Versioning,即 “基于 Web 的分布式编辑与版本控制”。顾名思义,其设计目的就是要实现“ Web 上的分布式(多人协作)编辑 ”,要让 Web 成为一个“可写、可协作”,而不仅仅是“可读”的媒体。WebDAV 协议为网络用户提供了一套框架,可以在服务器上进行文档的创建、修改和移动。
为完成上述的目标,WebDAV 在设计中融入了几个重要特征,
特征名称 | 特征说明 |
---|---|
文档作者或修改日期的属性维护 | 文件的创建、删除、查询的信息维护 |
命名空间管理 | 在服务器的命名空间中拷贝、移动 web 页面 |
资源集合管理 | 创建、删除、列表各种资源 |
写入覆盖保护机制 | 与文件的锁定、解锁相关(并发控制) |
在实现上,WebDAV 对 HTTP 1.1 协议进行了扩展,在 GET、POST、HEAD 等几个 HTTP 标准方法以外添加了一些新的方法,以此提供并发控制和命名空间的操作的手段,使应用程序可对 Web Server 直接读写,并支持写文件锁定 (Locking) 及解锁 (Unlock),及文件的版本控制。
很多“网盘”的相关功能,都是靠 WebDAV 的支持来实现。
Nginx 中设置 WebDAV 支持
(1) DAV 支持的模块
nginx 通过模块实现对 DAV 的支持。主要模块有如下两个,
- ngx_http_dav_module 模块
nginx 中标准的 dav 模块。对 dav 实现有限的支持,只支持 GET,HEAD,PUT,DELETE,MKCOL,COPY,MOVE 这几个方法。
-
nginx 的 dav 扩展模块。dav 的完整支持。补充了 ngx_http_dav_module 中缺少的方法,如 PROPFIND, PROPPATCH, OPTIONS, LOCK, UNLOCK。
要获得 WebDAV 完整的功能,需要上述两个模块都启动。
(2) DAV 模块安装
- 源码编译安装
## 下载 dav 扩展模块源码 cd /usr/local/src && git clone --recursive https://github.com/arut/nginx-dav-ext-module ## 编译安装 ./configure \ --with-http_dav_module \ --add-module=/usr/local/src/nginx-dav-ext-module make && make install
- apt 安装
apt install nginx-extras
(3) DAV 模块的配置示例
server {
listen 8000;
root /var/www/html/webdav/;
# 认证方式
auth_basic "Please input password"; #这里是验证时的提示信息
# 存放认证用户名、密码文件(确认有对应权限)
auth_basic_user_file /etc/nginx/sites-available/passwd;
autoindex on; # 开启目录文件列表
# DAV支持的请求方法
dav_methods PUT DELETE MKCOL COPY MOVE;
# DAV扩展支持的请求方法
dav_ext_methods PROPFIND OPTIONS;
# 文件和文件夹设置默认权限
dav_access user:rw group:rw all:r;
# WebDAV 默认只能在已存在的目录中创建文件;
# 开启本选项,可以自动创建所需的目录
create_full_put_path on;
}
SSL 参数设置
server {
......
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
### SSL 证书文件
ssl_certificate /etc/letsencrypt/live/jiatcool.com/fullchain.pem;
### SSL 私钥文件
ssl_certificate_key /etc/letsencrypt/live/jiatcool.com/privkey.pem;
### SSL 可选配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
......
}
### 对 http://example.com 访问进行处理,重定向到 https 访问
server {
listen 80;
listen [::]:80;
server_name example.com;
### 强制重定向到 https
return 301 https://$host$request_uri;
}
Ngnix 特色场景设置
反向代理参数设置
负载均衡参数设置
动静结合设置
Reference
- https://www.cnblogs.com/yangyh11/p/9801466.html
- https://www.youtube.com/playlist?list=PLmOn9nNkQxJFqjd8stdqdXgTnDDpr0baO
- Nginx concepts I wish I knew years ago (中文)
- https://blog.csdn.net/weixin_34290390/article/details/92931579
- https://zhuanlan.zhihu.com/p/348351797
- https://juejin.cn/post/7096443628326748174
- https://www.cnblogs.com/jiangxiaobo/p/10266308.html
- https://tengine.taobao.org/nginx_docs/cn/docs/http/request_processing.html
- https://blog.csdn.net/m414160547/article/details/101596576
WebDAV