Nginx(发音为"engine-x")是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。由俄罗斯程序员Igor Sysoev开发,以其高性能、稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。
了解Nginx的核心概念是掌握其使用方法的基础:
负载均衡是将请求分发到多个后端服务器的过程,以提高系统的可用性和性能:
Nginx作为静态文件服务器的优势:
虚拟主机允许在单个Nginx服务器上托管多个网站:
将静态资源和动态资源分开处理的架构模式:
Nginx采用事件驱动的异步非阻塞架构,这是其高性能的核心原因。下面详细解释其架构原理:
Nginx采用多进程模型,主要由两种进程组成:
Nginx的事件驱动模型是其高性能的关键:
Nginx使用非阻塞I/O和I/O多路复用技术处理并发连接:
| 技术 | 适用系统 | 特点 | 性能 |
|---|---|---|---|
| select | 跨平台 | 文件描述符数量限制(1024) | O(n) - 随连接数线性增长 |
| poll | 跨平台 | 无文件描述符数量限制 | O(n) - 随连接数线性增长 |
| epoll | Linux | 事件通知机制,只关注活跃连接 | O(1) - 不受连接数影响 |
| kqueue | FreeBSD/macOS | 类似epoll,事件通知机制 | O(1) - 不受连接数影响 |
| IOCP | Windows | Windows原生异步I/O | 高性能 |
Nginx实现了内存池机制,用于减少内存分配和释放的开销:
单个Worker进程处理连接的流程:
| 特性 | Nginx | Apache |
|---|---|---|
| 架构模型 | 事件驱动、异步非阻塞 | 进程/线程模型、同步阻塞 |
| 并发性能 | 高(适合高并发场景) | 中等(适合动态内容) |
| 内存消耗 | 低 | 较高 |
| 配置语法 | 简洁、模块化 | .htaccess、较复杂 |
| 适用场景 | 静态内容、反向代理、负载均衡 | 动态内容、模块丰富 |
Nginx支持多种安装方式,根据使用场景选择合适的安装方法:
# 更新软件包列表
sudo apt update
# 安装Nginx
sudo apt install nginx -y
# 查看Nginx版本
nginx -v
# 启动Nginx服务
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
# 检查服务状态
sudo systemctl status nginx
# 添加EPEL仓库(CentOS 7/8)
sudo yum install epel-release -y
# 安装Nginx
sudo yum install nginx -y
# 启动Nginx
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
# 配置防火墙(如果需要)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# 使用Homebrew安装
brew install nginx
# 启动Nginx
nginx
# 查看配置文件位置
nginx -t
# 重新加载配置
nginx -s reload
# 下载Windows版本的Nginx
# 访问 https://nginx.org/en/download.html 下载稳定版本
# 解压到C:\nginx目录
# 打开命令提示符,切换到nginx目录
cd C:\nginx
# 启动Nginx
start nginx
# 停止Nginx
nginx -s stop
# 拉取官方Nginx镜像
docker pull nginx:latest
# 运行Nginx容器
docker run --name mynginx -p 80:80 -d nginx
# 查看运行状态
docker ps
# 进入容器查看配置
docker exec -it mynginx bash
编译安装可以获得最佳性能和自定义功能,但需要更多步骤:
# 安装编译依赖
sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev -y
# 下载Nginx源码
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 配置编译选项(根据需求选择模块)
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-threads \
--with-file-aio
# 编译并安装
make && sudo make install
# 创建系统服务文件
sudo nano /etc/systemd/system/nginx.service
掌握Nginx的基本命令是运维的基础,以下是常用的命令:
# 启动Nginx
nginx
# 停止Nginx(快速停止,立即终止)
nginx -s stop
# 停止Nginx(优雅停止,等待worker进程处理完当前请求)
nginx -s quit
# 重新加载配置文件(不停止服务,平滑重启)
nginx -s reload
# 重新打开日志文件(用于日志切割)
nginx -s reopen
# 测试配置文件语法是否正确
nginx -t
# 测试并显示配置文件路径
nginx -T
# 启动Nginx服务
sudo systemctl start nginx
# 停止Nginx服务
sudo systemctl stop nginx
# 重启Nginx服务
sudo systemctl restart nginx
# 重新加载配置(不重启服务)
sudo systemctl reload nginx
# 查看服务状态
sudo systemctl status nginx
# 设置开机自启
sudo systemctl enable nginx
# 禁用开机自启
sudo systemctl disable nginx
# 查看服务日志
sudo journalctl -u nginx -f
# 查看Nginx进程
ps aux | grep nginx
# 查看Nginx监听的端口
netstat -tlnp | grep nginx
# 查看Nginx版本和编译信息
nginx -V
# 强制杀死Nginx进程
pkill -9 nginx
练习1:在本地环境中安装Nginx,并验证安装是否成功
练习2:使用nginx -t命令测试配置文件语法
练习3:尝试使用不同的停止命令,观察区别
练习4:查看Nginx进程和监听的端口
了解Nginx的目录结构有助于更好地管理配置:
/etc/nginx/ # 配置文件目录
├── nginx.conf # 主配置文件
├── conf.d/ # 额外的配置文件
├── sites-available/ # 可用的虚拟主机配置
├── sites-enabled/ # 启用的虚拟主机配置(符号链接)
├── modules-available/ # 可用模块
└── modules-enabled/ # 启用模块
/var/log/nginx/ # 日志文件目录
├── access.log # 访问日志
└── error.log # 错误日志
/var/www/html/ # 默认网站根目录
/usr/share/nginx/ # 共享文件目录
/usr/sbin/nginx # Nginx可执行文件
/usr/local/nginx/ # 安装根目录
├── conf/ # 配置文件目录
├── html/ # 网站根目录
├── logs/ # 日志文件目录
├── sbin/ # 可执行文件目录
└── temp/ # 临时文件目录
nginx -V 命令可以查看编译时的配置路径。
Nginx的配置文件是其功能强大的关键,了解配置文件的结构和指令是掌握Nginx的基础:
Nginx主配置文件(通常是 nginx.conf)的基本结构如下:
user nginx; # 运行Nginx的用户
worker_processes auto; # Worker进程数量,auto表示自动设置为CPU核心数
error_log /var/log/nginx/error.log warn; # 错误日志路径和级别
pid /var/run/nginx.pid; # PID文件路径
# 事件模块配置
events {
worker_connections 1024; # 每个Worker进程的最大连接数
use epoll; # 使用的事件驱动模型
}
# HTTP模块配置
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; # 启用sendfile系统调用
tcp_nopush on; # 启用TCP_NOPUSH选项
tcp_nodelay on; # 启用TCP_NODELAY选项
keepalive_timeout 65; # Keep-Alive超时时间
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream backend {
server backend1.example.com:8080 weight=5;
server backend2.example.com:8080 weight=3;
server backend3.example.com:8080 backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
# 测试配置文件语法是否正确
nginx -t
# 测试并显示配置文件内容
nginx -T
# 重新加载配置文件(不停止服务)
nginx -s reload
# 使用systemctl重新加载配置
sudo systemctl reload nginx
nginx -t 测试语法是否正确,然后再重载配置。这样可以避免配置错误导致服务中断。
# 检查80端口是否被占用
sudo netstat -tlnp | grep :80
# 如果被占用,可以停止占用进程或修改Nginx监听端口
sudo kill -9 [PID]
# 或者修改Nginx配置文件中的监听端口
listen 8080;
# Nginx需要读取网站文件的权限
sudo chown -R www-data:www-data /var/www/html/
sudo chmod -R 755 /var/www/html/
# 如果使用非标准端口(<1024),需要root权限
sudo nginx
# 测试配置文件语法
nginx -t
# 如果出现错误,检查错误信息指向的行号
# 常见的语法错误包括:
# - 缺少分号 ;
# - 括号不匹配 { }
# - 指令拼写错误
通过本课的学习,你应该已经掌握了:
Nginx的版本选择:
性能监控:可以使用 nginx -V 查看编译参数,确保启用了性能相关的模块。
任务1:在本地环境中成功安装并启动Nginx
任务2:熟悉Nginx的基本命令,能够进行服务管理
任务3:了解Nginx的目录结构,找到关键配置文件
任务4:尝试修改默认端口,并验证配置生效
安装完成后,在浏览器中访问 http://localhost 或 http://服务器IP,如果看到"Welcome to nginx!"页面,说明安装成功。
# CentOS/RHEL
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
# Ubuntu/Debian
sudo ufw allow 'Nginx HTTP'
下面介绍几个Nginx的常见实战场景,帮助你掌握实际应用中的配置方法:
部署一个基本的静态网站,包括HTML、CSS、JS和图片等静态资源:
# 创建网站根目录
sudo mkdir -p /var/www/example.com/html
# 创建示例HTML文件
sudo nano /var/www/example.com/html/index.html
# 创建网站配置文件
sudo nano /etc/nginx/sites-available/example.com
配置内容:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
# 静态文件缓存设置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
# 防盗链设置
location ~* \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked example.com www.example.com;
if ($invalid_referer) {
return 403;
}
}
# 主页面访问
location / {
try_files $uri $uri/ =404;
}
# 404错误页面
error_page 404 /404.html;
location = /404.html {
internal;
}
}
# 创建符号链接
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# 测试配置
sudo nginx -t
# 重载配置
sudo nginx -s reload
将Nginx配置为反向代理,转发请求到后端的应用服务器:
server {
listen 80;
server_name api.example.com;
# 反向代理配置
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# 健康检查
location /health {
proxy_pass http://localhost:3000/health;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
}
配置Nginx实现负载均衡,分发请求到多个后端服务器:
# 定义后端服务器集群
upstream backend_servers {
# 轮询方式(默认)
server 192.168.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=2 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name lb.example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream backend_servers {
# IP哈希方式,保证同一客户端请求到同一服务器
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name lb.example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
}
}
配置Nginx支持HTTPS,使用SSL证书加密传输:
# 使用Let's Encrypt获取免费证书
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com -d www.example.com
server {
listen 80;
server_name example.com www.example.com;
# 重定向HTTP到HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS设置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
配置Nginx实现动静分离,静态资源由Nginx直接处理,动态请求转发到后端服务器:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# 静态资源处理
location ~* \.(html|css|js|jpg|jpeg|png|gif|ico|svg)$ {
expires 7d;
add_header Cache-Control "public, max-age=604800";
try_files $uri =404;
}
# 动态请求转发到PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# API请求转发到后端服务
location /api/ {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
使用Nginx的rewrite指令实现URL重写和重定向:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.html;
# 重定向www到非www
if ($host = 'www.example.com') {
return 301 https://example.com$request_uri;
}
# 重定向HTTP到HTTPS
if ($scheme != 'https') {
return 301 https://$host$request_uri;
}
# URL重写示例
location /blog/ {
# 重写 /blog/123 为 /blog/post.php?id=123
rewrite ^/blog/([0-9]+)$ /blog/post.php?id=$1 last;
}
# 隐藏文件扩展名
location /docs/ {
rewrite ^/docs/(.*)$ /docs/$1.html last;
}
location / {
try_files $uri $uri/ =404;
}
}
nginx -v 查看版本信息nginx -s reload 重新加载配置nginx -t 测试配置文件ps aux | grep nginx优化Nginx性能可以显著提高网站的响应速度和并发处理能力。下面从多个方面详细介绍Nginx的性能优化方法:
# 设置Worker进程数量为CPU核心数
worker_processes auto;
# 绑定Worker进程到特定CPU核心(减少上下文切换)
worker_cpu_affinity 0001 0010 0100 1000;
# 设置每个Worker进程的最大打开文件数
worker_rlimit_nofile 65535;
# 开启Worker进程的最大连接数
events {
worker_connections 10240;
multi_accept on;
use epoll;
}
http {
# 启用sendfile系统调用,减少磁盘I/O
sendfile on;
# 启用tcp_nopush,与sendfile配合使用
tcp_nopush on;
# 启用tcp_nodelay,减少网络延迟
tcp_nodelay on;
# 调整Keep-Alive超时时间
keepalive_timeout 65;
keepalive_requests 10000;
# 调整客户端请求体缓冲区大小
client_body_buffer_size 16k;
client_max_body_size 10m;
# 调整请求头缓冲区大小
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
# 启用gzip压缩
gzip on;
gzip_comp_level 6;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
# 限制请求处理时间
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
}
修改Linux系统内核参数,提高Nginx的性能:
# 编辑sysctl.conf文件
sudo nano /etc/sysctl.conf
# 添加以下配置
# 最大文件句柄数
fs.file-max = 65535
# 网络相关优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# TCP相关优化
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.ip_local_port_range = 1024 65535
# 应用配置
sudo sysctl -p
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
add_header Last-Modified "$date_gmt";
add_header ETag "$etag";
try_files $uri =404;
}
# 定义缓存路径
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
location / {
# 使用缓存
proxy_cache my_cache;
proxy_cache_valid 200 304 1h;
proxy_cache_valid any 10m;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_bypass $http_pragma;
proxy_cache_bypass $http_cache_control;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}
# 定义FastCGI缓存路径
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
location ~ \.php$ {
fastcgi_cache fastcgi_cache;
fastcgi_cache_valid 200 304 1h;
fastcgi_cache_valid any 10m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_bypass $http_pragma;
fastcgi_cache_bypass $http_cache_control;
add_header X-FastCGI-Cache-Status $upstream_cache_status;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
# 安装ngx_http_limit_req_module和ngx_http_limit_conn_module模块
# 定义限制区域
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
# 限制请求速率
limit_req zone=req_limit burst=20 nodelay;
# 限制并发连接数
limit_conn conn_limit 10;
}
}
server {
# 客户端连接超时设置
client_body_timeout 12s;
client_header_timeout 12s;
# 代理超时设置
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
proxy_send_timeout 10s;
# FastCGI超时设置
fastcgi_connect_timeout 10s;
fastcgi_read_timeout 60s;
fastcgi_send_timeout 10s;
}
upstream backend {
# 使用最少连接数算法
least_conn;
# 配置后端服务器权重
server backend1.example.com:8080 weight=5 max_fails=3 fail_timeout=30s;
server backend2.example.com:8080 weight=3 max_fails=3 fail_timeout=30s;
server backend3.example.com:8080 weight=2 max_fails=3 fail_timeout=30s backup;
# 启用健康检查
check interval=3000 rise=2 fall=3 timeout=1000;
}
gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-javascript application/vnd.ms-fontobject application/font-sfnt font/opentype font/ttf font/eot font/woff font/woff2 image/svg+xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
brotli on;
brotli_comp_level 6;
brotli_min_length 1024;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/x-javascript application/vnd.ms-fontobject application/font-sfnt font/opentype font/ttf font/eot font/woff font/woff2 image/svg+xml;
server {
listen 443 ssl http2;
# SSL配置
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 其他配置
}
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# 测试100个并发连接,共10000个请求
ab -n 10000 -c 100 http://localhost/
Q: 端口80被占用怎么办?
A: 可以修改配置文件中的监听端口,或者停止占用80端口的程序。
Q: 如何卸载Nginx?
# Ubuntu/Debian
sudo apt remove nginx -y
# CentOS/RHEL
sudo yum remove nginx -y
# 编译安装的版本
sudo rm -rf /usr/local/nginx
安全配置是Nginx部署中的重要环节,合理的安全配置可以有效防止各种网络攻击。下面详细介绍Nginx的安全配置方法:
# 安装certbot
sudo apt install certbot python3-certbot-nginx -y
# 自动获取证书并配置Nginx
sudo certbot --nginx -d example.com -d www.example.com
# 测试自动续期
sudo certbot renew --dry-run
# 设置自动续期定时器
sudo systemctl enable certbot.timer
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL证书路径
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# SSL协议版本
ssl_protocols TLSv1.2 TLSv1.3;
# SSL密码套件
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS设置
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 防止点击劫持
add_header X-Frame-Options SAMEORIGIN;
# 防止MIME类型嗅探
add_header X-Content-Type-Options nosniff;
# 启用XSS保护
add_header X-XSS-Protection "1; mode=block";
# 其他配置
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# HTTP重定向到HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# 允许特定IP访问
location /admin/ {
allow 192.168.1.100;
allow 10.0.0.0/24;
deny all;
# 其他配置
}
# 拒绝特定IP访问
location / {
deny 192.168.1.200;
deny 172.16.0.0/16;
allow all;
# 其他配置
}
# 安装Apache工具生成密码文件
sudo apt install apache2-utils -y
# 创建密码文件
sudo htpasswd -c /etc/nginx/.htpasswd admin
# 添加用户
sudo htpasswd /etc/nginx/.htpasswd user1
# 配置密码访问
location /admin/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
# 其他配置
}
location / {
# 只允许GET、POST和HEAD方法
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405;
}
# 其他配置
}
# 启用ufw
sudo ufw enable
# 允许SSH访问
sudo ufw allow ssh
# 允许HTTP和HTTPS访问
sudo ufw allow 'Nginx Full'
# 查看防火墙状态
sudo ufw status
# 启用firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
# 允许SSH访问
sudo firewall-cmd --permanent --add-service=ssh
# 允许HTTP和HTTPS访问
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# 重新加载防火墙规则
sudo firewall-cmd --reload
# 查看防火墙状态
sudo firewall-cmd --state
sudo firewall-cmd --list-all
# 限制请求速率
limit_req_zone $binary_remote_addr zone=ddos:10m rate=10r/s;
server {
location / {
limit_req zone=ddos burst=20 nodelay;
# 其他配置
}
}
# 限制并发连接数
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
limit_conn conn_limit 10;
# 其他配置
}
}
# 过滤SQL注入特征
if ($request_uri ~* "('|"|;|--|union|select|insert|drop|update|delete|alter)") {
return 403;
}
# 对用户输入进行验证
location ~ \.php$ {
# 其他FastCGI配置
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 启用XSS保护头部
add_header X-XSS-Protection "1; mode=block";
# 使用Content-Security-Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:;";
# 对用户输入进行转义
# 注意:这主要在应用程序层面实现
# 设置X-Frame-Options头部
add_header X-Frame-Options SAMEORIGIN;
# 或者使用Content-Security-Policy
add_header Content-Security-Policy "frame-ancestors 'self';";
# 在http块中添加
server_tokens off;
# 编译时隐藏版本信息(更彻底)
./configure --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_sub_module --with-http_v2_module --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock
# 在全局块中设置
user nginx nginx;
# 创建nginx用户和组(如果不存在)
sudo useradd -M -s /sbin/nologin nginx
# 设置文件和目录权限
sudo chown -R nginx:nginx /var/www/html
sudo chmod -R 755 /var/www/html
sudo chmod 600 /etc/nginx/.htpasswd
sudo chmod 644 /etc/nginx/nginx.conf
sudo chmod -R 644 /etc/nginx/conf.d/
# 编译时只包含必要的模块
./configure --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module
# 或者在配置文件中禁用模块
# load_module modules/ngx_http_geoip_module.so;
访问 SSL Labs 输入你的域名,获取SSL配置的安全评分和改进建议。
# 安装Fail2ban
sudo apt install fail2ban -y
# 配置Fail2ban
sudo nano /etc/fail2ban/jail.local
# 添加Nginx配置
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 3600
# 启动Fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# 查看Fail2ban状态
sudo fail2ban-client status
有效的日志管理和监控是保证Nginx稳定运行的重要手段。下面详细介绍Nginx的日志管理和监控方法:
# 主配置文件中的日志格式定义
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;
# 错误日志配置
error_log /var/log/nginx/error.log warn;
# 详细的访问日志格式
log_format detailed '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time $upstream_status';
# JSON格式日志(便于日志分析工具处理)
log_format json '{'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"time_local":"$time_local",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time"'
'}';
# 使用自定义日志格式
access_log /var/log/nginx/access_detailed.log detailed;
access_log /var/log/nginx/access_json.log json;
server {
listen 80;
server_name example.com;
# 为该站点单独设置访问日志
access_log /var/log/nginx/example.com.access.log main;
error_log /var/log/nginx/example.com.error.log warn;
# 其他配置
}
server {
listen 80;
server_name api.example.com;
# 为API站点单独设置访问日志
access_log /var/log/nginx/api.example.com.access.log json;
error_log /var/log/nginx/api.example.com.error.log error;
# 其他配置
}
# Nginx的logrotate配置文件通常位于 /etc/logrotate.d/nginx
# 查看现有配置
cat /etc/logrotate.d/nginx
# 编辑Nginx的logrotate配置
sudo nano /etc/logrotate.d/nginx
配置内容:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
# 测试日志轮转配置
sudo logrotate -d /etc/logrotate.d/nginx
# 强制执行日志轮转
sudo logrotate -f /etc/logrotate.d/nginx
# 统计访问量最高的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 统计访问量最高的URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
# 统计平均响应时间
awk '{sum+=$10} END {print sum/NR}' /var/log/nginx/access.log
# 安装goaccess
sudo apt install goaccess -y
# 实时分析日志并生成HTML报告
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html
# 生成静态HTML报告
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED
# 检查stub_status模块是否已安装
nginx -V 2>&1 | grep -o with-http_stub_status_module
# 在配置文件中添加stub_status配置
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
# 使用curl访问状态页面
curl http://localhost/nginx-status
# 输出示例:
# Active connections: 2
# server accepts handled requests
# 12345 12345 67890
# Reading: 0 Writing: 1 Waiting: 1
# 安装htop
sudo apt install htop -y
# 运行htop查看系统资源使用情况
top
htop
# 查看系统虚拟内存统计
vmstat 1
# 查看CPU使用情况
mpstat 1
# 查看磁盘I/O情况
iostat -x 1
# 查看Nginx的网络连接
netstat -tulpn | grep nginx
ss -tulpn | grep nginx
# 查看当前连接数
netstat -an | grep ESTABLISHED | wc -l
ss -s
# 安装Nagios插件
sudo apt install nagios-plugins -y
# 监控Nginx服务状态
check_http -H localhost -I 127.0.0.1 -p 80
# 监控Nginx状态页面
check_http -H localhost -I 127.0.0.1 -p 80 -u /nginx-status
# 实时查看错误日志
tail -f /var/log/nginx/error.log
# 查看最近的错误
tail -n 100 /var/log/nginx/error.log | grep -i error
# 查看特定时间的错误
awk '$0 ~ "2024/01/01" && $0 ~ "error"' /var/log/nginx/error.log
# 查看4xx和5xx错误
awk '$9 >= 400' /var/log/nginx/access.log | head -20
# 查看响应时间较长的请求
awk '$10 > 5' /var/log/nginx/access.log | head -20
# 查看访问量异常的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# 测试配置文件语法
nginx -t
# 查看完整的配置
nginx -T
# 查看Nginx版本和编译选项
nginx -V
Nginx的功能是通过模块化设计实现的,核心功能由核心模块提供,扩展功能由第三方模块提供。下面详细介绍Nginx的常用模块:
核心HTTP模块,提供HTTP基本功能:
访问控制模块,基于IP地址控制访问:
location /admin/ {
allow 192.168.1.100;
allow 10.0.0.0/24;
deny all;
}
基于HTTP基本认证的访问控制模块:
location /secure/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
Gzip压缩模块,用于压缩HTTP响应:
gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
日志模块,用于记录HTTP请求:
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;
URL重写模块,用于修改请求URI:
location /blog/ {
rewrite ^/blog/([0-9]+)$ /blog/post.php?id=$1 last;
}
location /old/ {
rewrite ^/old/(.*)$ /new/$1 permanent;
}
反向代理模块,用于将请求转发到后端服务器:
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
FastCGI模块,用于将请求转发到FastCGI服务器(如PHP-FPM):
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
SSL/TLS模块,用于HTTPS支持:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
# 其他配置
}
HTTP/2模块,支持HTTP/2协议:
server {
listen 443 ssl http2;
# 其他配置
}
状态监控模块,提供Nginx的状态信息:
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
真实IP模块,用于获取客户端的真实IP地址(当Nginx作为反向代理时):
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
GeoIP模块,基于客户端IP地址获取地理位置信息:
geoip_country /usr/share/GeoIP/GeoIP.dat;
geoip_city /usr/share/GeoIP/GeoIPCity.dat;
server {
location / {
add_header X-Country-Code $geoip_country_code;
add_header X-City $geoip_city;
# 根据国家重定向
if ($geoip_country_code = "US") {
return 301 https://us.example.com$request_uri;
}
}
}
内容替换模块,用于替换HTTP响应中的内容:
sub_filter 'old text' 'new text';
sub_filter_once off;
sub_filter_types text/html text/css text/javascript;
内容添加模块,用于在HTTP响应前后添加内容:
location / {
add_before_body /header.html;
add_after_body /footer.html;
}
安全链接模块,用于生成和验证安全链接:
location /download/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "secret$secure_link_expires$uri";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
# 其他配置
}
# 编译为动态模块
./configure --add-dynamic-module=../ngx_http_headers_more_filter_module
# 编译Nginx
make
make install
# 加载动态模块
load_module modules/ngx_http_headers_more_filter_module.so;
更强大的HTTP头部处理模块:
load_module modules/ngx_http_headers_more_filter_module.so;
server {
location / {
more_set_headers 'Server: MyServer';
more_set_headers 'X-Powered-By: Nginx';
more_clear_headers 'X-Powered-By';
}
}
Brotli压缩模块,提供比gzip更高的压缩率:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
brotli on;
brotli_comp_level 6;
brotli_min_length 1024;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 查看编译时的配置和模块
nginx -V
# 查看已加载的动态模块
nginx -m
--without-http_xxx_module 禁用load_module 指令加载nginx -t 测试# 核心模块
ngx_http_core_module
ngx_http_access_module
ngx_http_log_module
# 性能优化模块
ngx_http_gzip_module
ngx_http_brotli_module (动态)
ngx_http_static_module
ngx_http_autoindex_module
# 安全模块
ngx_http_ssl_module
ngx_http_secure_link_module
# 核心模块
ngx_http_core_module
ngx_http_proxy_module
ngx_http_log_module
# 性能优化模块
ngx_http_gzip_module
ngx_http_upstream_module
# 安全模块
ngx_http_ssl_module
ngx_http_realip_module
# 监控模块
ngx_http_stub_status_module
# 核心模块
ngx_http_core_module
ngx_http_proxy_module
ngx_http_rewrite_module
ngx_http_upstream_module
# 安全模块
ngx_http_ssl_module
ngx_http_auth_basic_module
ngx_http_secure_link_module
# 监控模块
ngx_http_stub_status_module
# 扩展模块
ngx_http_geoip_module
ngx_http_headers_more_filter_module (动态)
Nginx提供了许多高级功能,可以满足复杂的业务需求。下面详细介绍Nginx的高级功能:
Lua模块允许在Nginx配置中嵌入Lua脚本,实现复杂的业务逻辑:
# 方法1:使用OpenResty(已集成Lua模块的Nginx发行版)
sudo apt install openresty -y
# 方法2:编译安装Lua模块
# 下载LuaJIT
wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
tar -zxvf LuaJIT-2.0.5.tar.gz
cd LuaJIT-2.0.5
make && sudo make install
# 下载ngx_devel_kit
wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.1.tar.gz
tar -zxvf v0.3.1.tar.gz
# 下载lua-nginx-module
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.14.tar.gz
tar -zxvf v0.10.14.tar.gz
# 编译Nginx,添加Lua模块
./configure --add-module=../ngx_devel_kit-0.3.1 --add-module=../lua-nginx-module-0.10.14
make && sudo make install
# 在http块中添加Lua配置
http {
# Lua模块配置
lua_package_path "/usr/local/lib/lua/?.lua;;";
lua_package_cpath "/usr/local/lib/lua/?.so;;";
server {
location /lua {
# 直接执行Lua代码
content_by_lua_block {
ngx.say("Hello, Lua!")
ngx.say("Request URI: ", ngx.var.uri)
ngx.say("Client IP: ", ngx.var.remote_addr)
}
}
location /lua-file {
# 执行外部Lua文件
content_by_lua_file /etc/nginx/lua/hello.lua;
}
}
}
# 1. 实现API认证
location /api/ {
access_by_lua_block {
local token = ngx.var.http_authorization
if not token then
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- 验证token
local valid = validate_token(token)
if not valid then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
proxy_pass http://backend;
}
# 2. 实现速率限制
location /api/ {
access_by_lua_block {
local ip = ngx.var.remote_addr
local limit = 100 -- 每分钟请求数
local key = "rate_limit:" .. ip
local current = redis.get(key)
if current and tonumber(current) > limit then
ngx.exit(ngx.HTTP_TOO_MANY_REQUESTS)
end
if not current then
redis.setex(key, 60, 1)
else
redis.incr(key)
end
}
proxy_pass http://backend;
}
HTTP/3是HTTP协议的最新版本,基于QUIC协议,提供更快的连接建立和更好的多路复用性能。
# 编译支持HTTP/3的Nginx
# 下载quiche库
git clone --recursive https://github.com/cloudflare/quiche.git
# 编译Nginx,添加HTTP/3支持
./configure --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-quiche=../quiche
make && sudo make install
# 配置HTTP/3
server {
listen 443 ssl http2;
listen 443 quic reuseport;
server_name example.com;
# SSL配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# HTTP/3配置
ssl_protocols TLSv1.2 TLSv1.3;
add_header Alt-Svc "h3=":443"; "always;
# 其他配置
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 编译为动态模块
./configure --add-dynamic-module=../module_name
make && sudo make install
# 加载动态模块
load_module modules/ngx_http_module_name.so;
upstream backend {
server backend1.example.com:8080 max_fails=3 fail_timeout=30s;
server backend2.example.com:8080 max_fails=3 fail_timeout=30s;
server backend3.example.com:8080 backup;
}
# 编译安装ngx_http_upstream_check_module
./configure --add-module=../ngx_http_upstream_check_module
make && sudo make install
# 配置主动健康检查
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
# 主动健康检查配置
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\nHost: example.com\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
# 基于IP的限流
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
proxy_pass http://backend;
}
# 基于连接数的限流
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
location /download/ {
limit_conn conn_limit 10;
alias /var/www/download/;
}
# 限制下载速度为100KB/s
location /download/ {
limit_rate 100k;
alias /var/www/download/;
}
# 限制特定文件类型的速度
location ~* \.(zip|rar|exe)$ {
limit_rate 500k;
alias /var/www/download/;
}
# 编译安装ngx_http_upstream_consistent_hash_module
./configure --add-module=../ngx_http_upstream_consistent_hash_module
make && sudo make install
# 配置一致性哈希负载均衡
upstream backend {
consistent_hash $request_uri;
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080;
}
upstream backend {
least_conn;
server backend1.example.com:8080 weight=5;
server backend2.example.com:8080 weight=3;
server backend3.example.com:8080 weight=2;
}
upstream backend {
ip_hash;
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080 down;
}
# 与Consul集成
sudo apt install consul -y
# 配置Consul模板
sudo apt install consul-template -y
# 创建Nginx配置模板
# /etc/consul-template/templates/nginx.ctmpl
upstream backend {
{{range service "backend"}}
server {{.Address}}:{{.Port}};
{{end}}
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
# 启动Consul模板
consul-template -template "/etc/consul-template/templates/nginx.ctmpl:/etc/nginx/conf.d/api.conf:nginx -s reload"
server {
listen 80;
server_name api.example.com;
# API版本路由
location /api/v1/ {
proxy_pass http://backend_v1;
}
location /api/v2/ {
proxy_pass http://backend_v2;
}
# API认证
location /api/ {
access_by_lua_block {
local token = ngx.var.http_authorization
if not token then
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- 验证token
local valid = validate_token(token)
if not valid then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
proxy_pass http://backend;
}
}
# Dockerfile
FROM nginx:latest
# 复制配置文件
COPY nginx.conf /etc/nginx/nginx.conf
COPY conf.d/ /etc/nginx/conf.d/
# 复制网站文件
COPY html/ /usr/share/nginx/html/
# 暴露端口
EXPOSE 80 443
# 启动Nginx
CMD ["nginx", "-g", "daemon off;"]
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/
volumes:
- name: nginx-config
configMap:
name: nginx-config
---
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer