Nginx 从入门到精通

Nginx 从入门到精通 · 第1篇:初识 Nginx

什么是 Nginx? Nginx(发音 “engine-x”)是一个高性能的 HTTP 和反向代理服务器,由俄罗斯程序员 Igor Sysoev 于 2004 年开源。它的设计目标是解决 C10K 问题——即同时处理一万个并发连接。 核心特点: 事件驱动架构:不同于 Apache 的进程/线程模型,Nginx 使用异步非阻塞 I/O,单进程可处理数万并发 高并发能力:轻松支撑数万并发连接 低内存消耗:同等负载下,内存占用远低于 Apache 模块化设计:功能通过模块扩展,可按需编译 安装 Nginx CentOS / RHEL # 添加 EPEL 源 sudo yum install epel-release -y # 安装 sudo yum install nginx -y # 启动 sudo systemctl start nginx sudo systemctl enable nginx Ubuntu / Debian sudo apt update sudo apt install nginx -y sudo systemctl start nginx sudo systemctl enable nginx 源码编译(进阶) # 安装依赖 sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev # 下载并编译 wget https://nginx.org/download/nginx-1.26.0.tar.gz tar -zxvf nginx-1.26.0.tar.gz cd nginx-1.26.0 ./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_gzip_static_module \ --with-http_stub_status_module make && sudo make install 启动与停止 # systemd 管理(推荐) sudo systemctl start nginx sudo systemctl stop nginx sudo systemctl reload nginx # 平滑重载配置 sudo systemctl restart nginx sudo systemctl status nginx # 直接使用二进制 sudo nginx # 启动 sudo nginx -s stop # 快速停止 sudo nginx -s quit # 优雅停止(处理完当前请求) sudo nginx -s reload # 平滑重载配置 sudo nginx -s reopen # 重新打开日志文件 验证安装 浏览器访问 http://服务器IP,看到 Welcome to nginx 页面即成功。 ...

January 5, 2025 · 2 min · 397 words

Nginx 从入门到精通 · 第2篇:基础配置

配置文件结构回顾 Nginx 的配置遵循指令和块的层次结构: 指令名 参数; 块名 { ... } 每个指令以分号结尾,块用花括号包裹。 搭建一个静态文件服务器 最简单的例子 server { listen 80; server_name static.example.com; root /var/www/static; index index.html index.htm; } 将 HTML 文件放入 /var/www/static,浏览器访问 http://static.example.com 即可看到内容。 完整的静态服务器配置 server { listen 80; server_name static.example.com; root /var/www/static; index index.html; # 关闭目录列表(安全考虑) autoindex off; # 文件过期时间 location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public, no-transform"; } # 字体文件 location ~* \.(woff|woff2|ttf|otf|eot)$ { expires 30d; add_header Cache-Control "public, no-transform"; } # 禁止访问隐藏文件 location ~ /\. { deny all; return 404; } } 配置指令详解 listen 监听端口或 Unix Socket: ...

January 6, 2025 · 3 min · 492 words

Nginx 从入门到精通 · 第3篇:反向代理

什么是反向代理? 正向代理:代理客户端,帮助客户端访问它无法直接访问的资源(如翻墙、公司内网代理)。 反向代理:代理服务器,客户端不知道请求最终由哪台后端服务器处理。 客户端 → Nginx(反向代理)→ 后端服务器(Tomcat/Node.js/Python...) 反向代理的典型用途: 隐藏后端服务器真实地址 统一入口(一个域名对应多个后端服务) 负载均衡 SSL 终结(证书统一放在 Nginx 层) 缓存和静态资源分离 最简单的反向代理 server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:8080; } } 所有访问 api.example.com 的请求都会被转发到本机的 8080 端口。 proxy_pass 语法细节 带 URI vs 不带 URI # 不带 URI:将完整 URI 原样转发 location /api { proxy_pass http://backend; # 请求 /api/users → http://backend/api/users } # 带 URI(有 / 路径):匹配部分被替换 location /api { proxy_pass http://backend/; # 请求 /api/users → http://backend/users } location /api { proxy_pass http://backend/v2/; # 请求 /api/users → http://backend/v2/users } 这是最容易踩坑的地方。 记住一条规则: ...

January 7, 2025 · 3 min · 430 words

Nginx 从入门到精通 · 第4篇:负载均衡

为什么需要负载均衡? 当单台服务器扛不住流量时,就需要多台服务器分担压力。负载均衡的作用就是把请求合理地分发到多台后端服务器上。 ┌─ Server A (10.0.0.1:8080) 用户 → Nginx ──── ├─ Server B (10.0.0.2:8080) ├─ Server C (10.0.0.3:8080) └─ Server D (backup) upstream 配置 负载均衡的核心是 upstream 块: upstream backend { server 10.0.0.1:8080; server 10.0.0.2:8080; server 10.0.0.3:8080; } server { listen 80; location / { proxy_pass http://backend; } } 负载均衡算法 1. 轮询(Round Robin,默认) upstream backend { server 10.0.0.1:8080; server 10.0.0.2:8080; server 10.0.0.3:8080; } 请求按顺序轮流分配给每台服务器,适合各服务器配置相同的场景。 2. 加权轮询(Weighted) upstream backend { server 10.0.0.1:8080 weight=3; # 处理 3/6 的请求 server 10.0.0.2:8080 weight=2; # 处理 2/6 的请求 server 10.0.0.3:8080 weight=1; # 处理 1/6 的请求 } 权重越高流量越多,适合服务器性能不一的情况。 ...

January 8, 2025 · 3 min · 474 words

Nginx 从入门到精通 · 第5篇:HTTPS 配置

为什么需要 HTTPS? 加密:防止中间人窃听和篡改 身份验证:确认你访问的网站是真实的 SEO:Google 对 HTTPS 网站有排名加分 浏览器标记:HTTP 网站会被标记为"不安全" 合规要求:支付、隐私数据必须使用 HTTPS SSL/TLS 证书获取 Let’s Encrypt(免费推荐) 使用 Certbot 自动获取和续期: # 安装 Certbot sudo apt install certbot python3-certbot-nginx -y # 获取并自动配置 Nginx sudo certbot --nginx -d example.com -d www.example.com # 仅获取证书(手动配置) sudo certbot certonly --nginx -d example.com # 查看证书 sudo certbot certificates # 测试续期 sudo certbot renew --dry-run 配置自动续期 # 添加 cron 任务,每天检查两次 echo "0 */12 * * * /usr/bin/certbot renew --quiet" | sudo tee -a /etc/crontab Certbot 默认自动添加了 systemd timer,多数情况下无需手动添加 cron。 ...

January 9, 2025 · 3 min · 489 words

Nginx 从入门到精通 · 第6篇:缓存机制

为什么需要缓存? 缓存的核心是用空间换时间——把处理过的结果存起来,下次直接返回,避免重复计算。 场景对比: 场景 无缓存 有缓存 首页加载 200ms + 后端渲染 5ms 直接返回 热点文章 每次都要查数据库 静态 HTML 直接返回 API 响应 每次都要执行业务逻辑 缓存期直接返回 Nginx 缓存体系 Nginx 的缓存分为两个层面: 代理缓存(Proxy Cache):在 Nginx 层缓存后端响应 浏览器缓存:通过响应头控制浏览器本地缓存 一、代理缓存 基础配置 # 在 http 块中定义缓存路径 http { proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off; server { location / { proxy_pass http://backend; proxy_cache my_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_valid any 1m; } } } 参数说明 参数 说明 示例 levels 缓存目录层级 1:2 → /c/29 keys_zone 缓存键的内存区域 my_cache:10m(10MB 约存 80000 个 key) max_size 缓存最大磁盘占用 1g inactive 缓存未被访问后的保留时间 60m use_temp_path 是否使用临时路径 off(直接写入缓存目录) 缓存命中判断 添加响应头来查看缓存状态: ...

January 10, 2025 · 3 min · 524 words

Nginx 从入门到精通 · 第7篇:重写规则

Location 匹配规则 location 决定了请求 URI 被哪个配置块处理,是 Nginx 最核心也是最容易搞混的指令之一。 匹配优先级 location = /exact { # 1. 精确匹配(最高优先级) ... } location ^~ /static/ { # 2. 优先前缀匹配 ... } location ~ \.php$ { # 3. 正则匹配(大小写敏感) ... } location ~* \.(jpg)$ { # 4. 正则匹配(大小写不敏感) ... } location / { # 5. 通用前缀匹配(最低优先级) ... } 匹配流程: 请求 /logo.jpg 1. 先匹配前缀 location —— 找到最长的匹配 2. 如果是 ^~ 匹配 → 直接使用,跳过正则 3. 否则按顺序检查正则 location 4. 如果正则匹配 → 使用正则 location 5. 如果正则都不匹配 → 使用第1步找到的最长前缀匹配 完整的优先级示例 server { root /var/www/html; location = / { # 精确匹配 / → /var/www/html/index.html try_files /index.html =404; } location = /favicon.ico { # 精确匹配 log_not_found off; access_log off; } location ^~ /static/ { # 优先前缀 root /var/www; expires 30d; } location ~ \.php$ { # 正则匹配 PHP fastcgi_pass unix:/var/run/php-fpm.sock; include fastcgi_params; } location ~* \.(jpg|png|gif)$ { # 正则匹配图片 expires 7d; } location / { # 兜底 try_files $uri $uri/ /index.php?$query_string; } } location 嵌套 Nginx 不支持 location 嵌套,但可以通过一些技巧模拟: ...

January 11, 2025 · 4 min · 653 words

Nginx 从入门到精通 · 第8篇:限流与防护

为什么需要限流? 没有限流的服务就像没有护栏的桥——当流量超出设计容量时: 数据库连接池耗尽 CPU 打满,响应时间飙升 服务雪崩:一台挂了,流量转移到其他机器,引发连锁反应 恶意攻击:暴力破解、爬虫、DDoS Nginx 内置的限流能力可以在请求到达后端之前就进行控制。 一、连接数限制(limit_conn) 限制同一 IP 的并发连接数: http { limit_conn_zone $binary_remote_addr zone=conn_zone:10m; server { location / { limit_conn conn_zone 10; # 每个 IP 最多 10 个并发连接 limit_conn_status 503; # 超限时返回 503 limit_conn_log_level warn; # 日志级别 } location /download/ { limit_conn conn_zone 5; # 下载区限制更严格 } } } $binary_remote_addr 比 $remote_addr 占用更少内存(10MB 约存 16 万个 IP)。 按域名限制 http { limit_conn_zone $server_name zone=site_zone:10m; server { location / { limit_conn site_zone 100; # 整个站点最多 100 个并发 } } } 二、请求频率限制(limit_req) 限制每秒的请求数,基于漏桶算法: ...

January 12, 2025 · 4 min · 655 words

Nginx 从入门到精通 · 第9篇:日志管理

日志体系 Nginx 有两类日志: 访问日志(access_log):记录每次请求的详细信息 错误日志(error_log):记录 Nginx 运行时的错误和警告 一、访问日志 默认配置 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; } 自定义日志格式 log_format json escape=json '{' '"time_local":"$time_local",' '"remote_addr":"$remote_addr",' '"remote_user":"$remote_user",' '"request":"$request",' '"status":$status,' '"body_bytes_sent":$body_bytes_sent,' '"request_time":$request_time,' '"upstream_response_time":"$upstream_response_time",' '"http_referer":"$http_referer",' '"http_user_agent":"$http_user_agent",' '"http_x_forwarded_for":"$http_x_forwarded_for",' '"cache_status":"$upstream_cache_status"' '}'; JSON 格式的日志更方便被日志收集系统(ELK、Loki)解析。 条件日志 # 不记录健康检查请求 map $uri $loggable { /health 0; default 1; } server { access_log /var/log/nginx/access.log main if=$loggable; } 按域名分拆日志 http { log_format main '...'; server { server_name example.com; access_log /var/log/nginx/example.com.access.log main; } server { server_name blog.example.com; access_log /var/log/nginx/blog.example.com.access.log main; } } 缓冲区写入 高并发下,日志先写入缓冲区再批量写入磁盘,可提升性能: ...

January 13, 2025 · 3 min · 537 words

Nginx 从入门到精通 · 第10篇:性能优化

性能指标 在开始优化之前,先明确衡量标准: 指标 说明 目标 QPS 每秒查询数 越高越好 响应时间 请求处理时间 < 100ms 并发连接数 同时处理的连接 支持预设值 内存占用 进程内存 < 单核 50MB CPU 使用率 核心利用率 合理利用不空转 一、Worker 进程优化 进程数与连接数 # 设置为 CPU 核心数,auto 自动检测 worker_processes auto; # 绑定 Worker 到指定 CPU(避免进程在 CPU 间切换) worker_cpu_affinity auto; # 每个 Worker 的最大连接数 worker_connections 10240; # 最大文件描述符数(系统限制也要同步调整) worker_rlimit_nofile 65535; 计算公式: 最大并发连接数 = worker_processes × worker_connections 最大并发客户端数 = 最大并发连接数 / 2(一个请求需要两个连接:一个读一个写) 事件模型 events { use epoll; # Linux 最高效的事件模型 worker_connections 10240; multi_accept on; # 一次性接受所有新连接 accept_mutex on; # 防止惊群效应 } 模型 系统 说明 epoll Linux 2.6+ 默认,最高效 kqueue FreeBSD/macOS macOS 默认 select 通用 最差,备选 二、操作系统层面优化 文件描述符限制 # 查看当前限制 ulimit -n # 临时修改 ulimit -n 65535 # 永久修改 /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 TCP 内核参数 # /etc/sysctl.conf # 端口范围(TIME_WAIT 端口复用) net.ipv4.ip_local_port_range = 1024 65535 # TIME_WAIT 复用和快速回收 net.ipv4.tcp_tw_reuse = 1 # 减少 FIN-WAIT-2 超时 net.ipv4.tcp_fin_timeout = 30 # 最大 SYN 半连接数(防 SYN Flood) net.ipv4.tcp_max_syn_backlog = 65536 # 允许更多 TIME_WAIT 套接字 net.ipv4.tcp_max_tw_buckets = 2000000 # TCP 读写缓冲区 net.core.rmem_default = 65536 net.core.wmem_default = 65536 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # SOMAXCONN(listen 队列长度) net.core.somaxconn = 65535 # 应用后生效 sudo sysctl -p 三、代理性能优化 启用 keepalive upstream backend { server 10.0.0.1:8080; keepalive 32; # 保持 32 个空闲长连接 keepalive_requests 1000; # 每个连接最多处理 1000 个请求 keepalive_timeout 60s; # 空闲超时 60 秒 } server { location / { proxy_pass http://backend; proxy_http_version 1.1; # 必须 HTTP/1.1 proxy_set_header Connection ""; # 清空 Connection 头 } } 代理缓冲 # 响应缓冲 proxy_buffering on; proxy_buffer_size 4k; # 响应头缓冲区 proxy_buffers 8 16k; # 响应体缓冲区(8 个 16KB) proxy_busy_buffers_size 32k; # 忙时缓冲区 proxy_temp_file_write_size 32k; # 临时文件写入大小 # 禁用响应缓冲(SSE/WebSocket 等实时场景) location /events { proxy_buffering off; proxy_cache off; } 减少数据拷贝 # 零拷贝:数据从磁盘到网卡不经过用户空间 sendfile on; # 优化发送(合并小包) tcp_nopush on; # 减少延迟(立即发送小包) tcp_nodelay on; tcp_nopush 和 tcp_nodelay 看似矛盾,但配合使用效果很好: ...

January 1, 2025 · 4 min · 806 words