😎 Nginx(读作 “engine-ex”)
- 🌍 起源: Nginx 是由俄罗斯程序员 Igor Sysoev 编写的。
- 📅 发布时间: 2004年10月。
- 💡 目标: 作为一个试图回答公众发布的 C10K 问题。其中 C10k 是同时管理 10,000 个连接的挑战。
- 🏗️ 架构特点: Nginx 采用了事件驱动和异步架构,此设计使 Nginx 成为可扩展、高性能的服务器。
- 🌐 用途:
- 开源、轻量级和高性能的 Web 服务器。
- HTTP、HTTPS、SMTP、IMAP、POP3 协议的反向代理服务器。
- IMAP、POP3 和 IMAP 的 HTTP 负载均衡器。
- HTTP 缓存和电子邮件代理。
- 💭 简而言之: 我们可以说 Nginx 是一种用于处理并发请求的软件。🚀
🤔 为什么要使用 Nginx?
-
🔄 反向代理与负载均衡
- 反向代理: Nginx 允许我们在端口 80 上托管多个域名,同时可以使用由不同语言编写的后端服务。
- 负载均衡: 通过 Nginx,可以将多个提供相同功能的后端服务配置成彼此冗余,确保高可用性和服务的稳定性。
-
🌐 动静分离
- 访问日志、黑名单: Nginx 可以高效地处理日志记录和安全性相关的功能。
- 静态文件访问: 对于静态资源(如图片、CSS、JavaScript),Nginx 提供了极快的访问速度。
- 后台 Web 服务集中处理业务逻辑: 通过 Nginx 进行动静分离,后台 Web 服务可以专注于核心的业务逻辑处理,提高开发效率和响应速度。
-
🚀 高并发与低内存占用
- 由于其事件驱动和异步架构,Nginx 能够高效地支持高并发连接,同时内存占用较小。
-
🛠️ 配置文件动态修改
- Nginx 支持在不重启服务的情况下动态修改其配置文件,这为运维工作带来了极大的便利。
🌐 Nginx 的工作机制
🚀 Nginx 进程:
1. 🧠 Master 进程 :
- 📜 负责加载和分析配置文件。
- 🤖 管理 worker 进程。
- 🔄 实现平滑升级。
- 📡 功能概述:
- 读取并验证 Nginx 配置文件的有效性和正确性。
- 按配置启动、管理和关闭 worker 进程。
- 接受来自外部的指令,如重启、升级或关闭服务器。
- 实现不中断服务的平滑升级,重启服务并应用新配置。
- 开启日志文件。
2. 🏃 Worker 进程 :
- 🌐 负责处理来自客户端的请求。
- 🔄 将请求一次送入各功能模块进行处理。
- 📞 进行 I/O 调用,获取响应数据。
- 🤝 与后端服务器通信并接收其处理结果。
- 🗂️ 管理数据缓存,访问缓存索引,并查询与调用缓存数据。
- 📤 发送请求的结果,响应客户端。
- 📡 接收来自 master 进程的指令。
3. 🗄️ Cache 相关进程 :
- Cache loader:
- 在 Nginx 服务启动后由 master 进程生成。
- 负责根据本地磁盘上的缓存建立索引元数据库。
- 完成任务后退出。
- Cache manager:
- 在元数据更新完成后运行。
- 判断元数据是否过期。
4. 📝 简要归纳:
-
Master 进程 🧠: 负责配置文件的加载和分析,管理 worker 进程,并实现平滑升级。
-
Worker 进程 🏃: 负责接收客户端请求,处理请求,与后端通信,管理数据缓存,和发送响应。
-
Cache 进程 🗄️: 包括 cache loader (用于缓存索引重建) 和 cache manager (用于缓存索引管理)。
🛠️ Nginx 的模块结构
🔶 核心模块 (Core Modules):
- HTTP 模块: 提供了 HTTP/HTTPS 服务的基础功能。
- EVENT 模块: 处理事件驱动模型,如连接和请求的读写。
- MAIL 模块: 提供邮件代理功能。
🔷 基础模块 (Base Modules):
- HTTP Access 模块: 控制基于 IP 或密码的访问。
- HTTP FastCGI 模块: 提供与 FastCGI 服务器的交互。
- HTTP Proxy 模块: 提供反向代理功能。
- HTTP Rewrite 模块: 提供 URL 重写功能。
🟢 动态模块 (Dynamic Modules):
- 这些模块可以在 Nginx 运行时动态地加载或卸载,而无需重新编译整个 Nginx。
- 它们提供了与静态模块相同的功能,但增加了更大的灵活性和方便性。
🔵 第三方模块 (Third-party Modules):
- HTTP Upstream Request Hash 模块: 提供负载均衡功能。
- Notice 模块: 提供特定的通知功能。
- HTTP Access Key 模块: 提供基于访问密钥的访问控制。
- 以及用户自定义和开发的其他模块。
🐧 在 Redhat/CentOS 上安装 Nginx
1️⃣ 从操作系统存储库安装 Nginx:
🔹 第 1 步: 安装 EPEL 存储库
- EPEL 代表 “额外的企业 Linux 包”。
- 由于默认的 yum 存储库中没有最新版本的 Nginx, 所以需要安装 EPEL。
sudo yum install epel-release
🔹 第 2 步: 更新存储库
sudo yum update
🔹 第 3 步: 安装 Nginx
yum install nginx
🔹 第 4 步: 验证安装
sudo nginx -v
2️⃣ 从官方 Nginx 存储库安装 Nginx:
🔸 第 1 步: 为 RHEL 或 CentOS 创建 yum 存储库
sudo vi /etc/yum.repos.d/nginx.repo
🔸 第 2 步: 在 nginx.repo
文件中添加以下内容
[nginx]
name=nginx repo
baseurl=https://nginx.org/packages/mainline/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1
- 替换
OS
为rhel
或centos
。 - 替换
OSRELEASE
为你的操作系统版本,如7
。
例如,对于 CentOS 7:
[nginx]
name=nginx repo
baseurl=https://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
🔸 第 3 步: 保存并退出 vi
编辑器
按 ESC
,然后输入 :wq
并按 Enter
。
🔸 第 4 步: 更新存储库
sudo yum update
🔸 第 5 步: 安装 Nginx
yum install nginx
🔸 第 6 步: 验证安装
sudo nginx -v
🖥️ 在 Windows 上安装 Nginx
1️⃣ 下载 Nginx:
- 访问 Nginx 的官方下载页面:https://nginx.org/en/download.html
- 下载最新的 Windows 版本,例如:https://nginx.org/download/nginx-1.20.2.zip
- 解压下载的文件到合适的文件夹,如:
c:\nginx-1.20.2
重要路径:
- 配置文件:
c:\nginx-1.20.2\conf\
- 默认配置:
c:\nginx-1.20.2\conf\nginx.conf
- 日志位置:
c:\nginx-1.20.2\logs
- 默认网站根目录:
c:\nginx-1.20.2\html
- 默认监听地址: http://localhost
2️⃣ 验证 Nginx 安装:
- 打开命令提示符 (CMD)
- 进入 Nginx 的目录
cd c:\nginx-1.20.2\
- 启动 Nginx
nginx.exe
- 打开浏览器并访问 http://localhost,如果看到 “Welcome to Nginx” 页面,表示 Nginx 已经成功安装。
3️⃣ Nginx 命令:
- 启动 Nginx:
nginx.exe
- 停止 Nginx:
nginx -s stop
- 优雅地停止 Nginx:
nginx -s quit
- 重载配置:
nginx -s reload
- 重新打开日志文件:
nginx -s reopen
注意: 在执行上述命令之前,确保已将 Nginx 的路径添加到了系统环境变量 Path
中。
4️⃣ 将 Nginx 安装为 Windows 服务:
- 下载 nssm: https://nssm.cc/release/nssm-2.24.zip
- 解压到
C:\nssm-2.24
- 使用命令行安装服务:
cd C:\nssm-2.24\win64
nssm install nginx
选择 nginx.exe
的路径,并点击安装服务。
- 删除 nginx 服务:
nssm remove nginx
- 启动和停止服务:
net start nginx
net stop nginx
5️⃣ 退出 Nginx:
如果任务管理器不能正常关闭 Nginx, 可以创建一个名为 stop.bat
的批处理文件,并添加以下内容:
@echo off
net stop nginx
taskkill /F /T /IM nginx.exe
双击 stop.bat
执行命令,即可停止 Nginx。
⚡️ 验证 Nginx 安装
1️⃣ 检查 Nginx 的版本:
🔹 通过以下命令验证 Nginx 是否已安装并检查其版本:
nginx -v
🔹 输出:
nginx version: nginx/1.20.0
2️⃣ 检查 Nginx 是否正在运行:
🔹 使用以下命令查看 Nginx 是否正在运行:
ps -ef | grep nginx
🔹 输出:
root 13705 1 0 Nov28 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
www 13707 13705 0 Nov28 ? 00:00:00 nginx: worker process
root 18830 13627 0 20:00 pts/2 00:00:00 grep --color=auto nginx
这里,我们看到了一个主进程和一个工作进程。如果 Nginx 正在运行,我们将始终看到一个主进程和一个或多个工作进程。因此,我们可以说我们安装的 Nginx 运行正常。
🔺 注意: 如果查不到 Nginx 进程,请先启动 Nginx。
3️⃣ 检查网络服务器状态:
🔹 使用以下命令检查 Nginx 服务的状态:
systemctl status nginx
🔹 输出:
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2021-06-16 20:43:10 CST; 6 months 3 days ago
Docs: http://nginx.org/en/docs/
Main PID: 25434 (nginx)
CGroup: /system.slice/nginx.service
├─25434 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
└─29190 nginx: worker process
此时,我们可以看到 Nginx 服务正在运行。
4️⃣ 通过浏览器验证:
🔹 打开浏览器并访问 http://localhost 或服务器的 IP 地址。你应该看到“Welcome to Nginx”默认页面。这表明 Nginx 服务运行正常。
🚀 启动和重启 Nginx
1️⃣ 启动 Nginx:
# 🔹 **使用 systemctl**:
sudo systemctl start nginx
# 🔹 **低于 Redhat 7 的版本**:
sudo service start nginx
# 🔹 **从源码编译安装**:
sudo nginx -s start
# 🔹 **旧的 Ubuntu Linux 版本**:
sudo /etc/init.d/nginx start
2️⃣ 启用 Nginx 服务:
# 🔹 **使用 systemctl**:
sudo systemctl enable nginx
# 🔹 **没有 systemd 的 Linux 发行版**:
sudo service nginx enable
3️⃣ 停止 Nginx:
# 🔹 **使用 systemctl**:
sudo systemctl stop nginx
# 🔹 **没有 systemd 的 Linux 发行版**:
sudo service stop nginx
# 🔹 **从源码编译安装**:
sudo nginx -s stop
# 🔹 **旧的 Ubuntu Linux 版本**:
sudo /etc/init.d/nginx stop
# 🔹 **向 Nginx 主进程发送信号**:
kill -QUIT $(cat /var/run/nginx.pid)
4️⃣ 重启 Nginx:
# 🔹 **使用 systemctl**:
sudo systemctl restart nginx
# 🔹 **没有 systemd 的 Linux 发行版**:
sudo service restart nginx
# 🔹 **旧的 Ubuntu Linux 版本**:
sudo /etc/init.d/nginx restart
5️⃣ 重新加载 Nginx:
# 🔹 **使用 systemctl**:
sudo systemctl reload nginx
# 🔹 **没有 systemd 的 Linux 发行版**:
sudo service reload nginx
# 🔹 **从源码编译安装**:
sudo nginx -s reload
6️⃣ 测试 Nginx 配置:
🔹 当我们更改 Nginx 的配置时,我们应该在重新启动或重新加载服务之前测试配置:
sudo nginx -t
🔹 输出:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
🎄 Nginx 目录结构
🔵 源码安装一般会把所有文件一起放到/usr/local/nginx
🔵 所有结尾为 default 的文件都是备份文件,其他未做注释的目录,为在生产环境中较少用到的目录。
[root@localhost ~]# tree /usr/local/nginx
/usr/local/nginx
├── client_body_temp # POST 大文件暂存目录
├── conf # Nginx所有配置文件的目录
│ ├── fastcgi.conf # fastcgi相关参数的配置文件
│ ├── fastcgi.conf.default # fastcgi.conf的原始备份文件
│ ├── fastcgi_params # fastcgi的参数文件
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types # 媒体类型
│ ├── mime.types.default
│ ├── nginx.conf #这是Nginx默认的主配置文件,日常使用和修改的文件
│ ├── nginx.conf.default
│ ├── scgi_params # scgi相关参数文件
│ ├── scgi_params.default
│ ├── uwsgi_params # uwsgi相关参数文件
│ ├── uwsgi_params.default
│ └── win-utf
├── fastcgi_temp # fastcgi临时数据目录
├── html # Nginx默认站点目录
│ ├── 50x.html # 错误页面优雅替代显示文件,例如出现502错误时会调用此页面
│ └── index.html # 默认的首页文件
├── logs # Nginx日志目录
│ ├── access.log # 访问日志文件
│ ├── error.log # 错误日志文件
│ └── nginx.pid # pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件
├── proxy_temp # 临时目录
├── sbin # Nginx 可执行文件目录
│ └── nginx # Nginx 二进制可执行程序
├── scgi_temp # 临时目录
└── uwsgi_temp # 临时目录
📊 Nginx 配置解析
📝 Nginx配置文件
Nginx 主配置文件 /etc/nginx/nginx.conf
是一个纯文本类型的文件,整个配置文件是以区块的形式组织。每个区块用大括号 {}
表示开始与结束。
✏️ 若编译安装则 nginx.conf
位于编译时所指定目录。
📌 层级结构:
- Main 位于
nginx.conf
配置文件的最高层;- Event 层,影响 Nginx 与用户的网络连接;
- HTTP 层,允许有多个 Server 层;
- Server 层,可以有多个 Location,对不同路径配置不同模块。
# 主配置 (Main Configuration)
user nginx; # 设置Nginx运行的用户
worker_processes 1; # 设置工作进程的数量
error_log /var/log/nginx/error.log warn; # 指定错误日志文件的位置
pid /var/run/nginx.pid; # 指定Nginx进程ID文件的存放路径
# 事件配置 (Events Configuration)
events {
worker_connections 1024; # 每个工作进程的最大连接数
}
# HTTP 配置 (HTTP Configuration)
http {
include /etc/nginx/mime.types; # 包含其他配置文件,这里是MIME类型的定义
default_type application/octet-stream; # 如果请求的文件的MIME类型未定义,则使用以下默认值
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; # 自定义日志格式
access_log /var/log/nginx/access.log main; # 指定访问日志的存放位置
sendfile on; # 允许Nginx使用sendfile系统调用来发送文件
keepalive_timeout 65; # 定义连接超时时间
# 服务器配置 (Server Configuration)
server {
listen 80; # 定义虚拟主机监听的端口号
server_name localhost; # 定义虚拟主机的名称
# 路径配置 (Location Configuration)
location / {
root /usr/share/nginx/html; # 定义网站的根目录
index index.html index.htm; # 定义默认的索引文件名
# 在此处可以为此路径添加其他配置。
}
error_page 500 502 503 504 /50x.html; # 定义错误页面
location = /50x.html {
root /usr/share/nginx/html; # 错误页面根目录
}
# 这里可以定义其他的路径。
}
# 在这里可以定义其他的服务器配置。
}
# 可在此处包含其他配置或模块。
🌎 Nginx 网站配置
为了新建一个虚拟主机,基于默认虚拟机 default.conf
:
[root@nginx ~]# vi /etc/nginx/conf.d/mysite.conf
server {
server_name www.lzq.com;
location / {
root /usr/share/nginx/base;
index index.html;
}
}
[root@lzq ~]# mkdir -p /usr/share/nginx/base
[root@lzq ~]# echo '<h1>lzq</h1>' > /usr/share/nginx/base/index.html
[root@lzq ~]# nginx -t -c /etc/nginx/nginx.conf #检查配置文件
[root@lzq ~]# nginx -s reload #重载配置文件
🚫 Nginx 自定义错误页面
[root@nginx ~]# vi /etc/nginx/conf.d/mystie.conf
server {
server_name www.lzq.com;
error_page 404 403 500 502 503 504 /error.html; #配置错误页
location / {
root /usr/share/nginx/base;
index index.html;
}
}
[root@lzq ~]# echo '<h1>Error</h1>' > /usr/share/nginx/error.html
[root@lzq ~]# nginx -t -c /etc/nginx/nginx.conf #检查配置文件
[root@lzq ~]# nginx -s reload #重载配置文件
🛡️ Nginx 相关安全策略
-
禁止访问
.htaccess
:location ~/\.ht { deny all; }
-
禁止访问多个目录:
location ~ ^/(picture|move)/ { deny all; break; }
-
禁止访问
/data
开头的文件:location ~ ^/data { deny all; }
-
禁止访问单个目录:
location /imxhy/images/ { deny all; }
-
允许特定 IP 访问:
root /usr/share/nginx/rewrite/; allow 208.97.167.194; allow 222.33.1.2; allow 231.152.49.4; deny all;