0.什么是Nginx?
Nginx(发音为 "engine-x")是一款高性能的 HTTP 服务器和反向代理服务器,同时也可用作邮件代理服务器和通用的 TCP/UDP 代理服务器。它由俄罗斯工程师 Igor Sysoev 于 2002 年开始开发,2004 年首次公开发布,旨在解决当时流行的 Apache HTTP Server 在高并发场景下的性能瓶颈。如今,Nginx 已成为全球最流行的 Web 服务器之一,被大量高流量网站(如 Netflix、GitHub、WordPress.com)所采用。
0.1 核心特性
- 高并发、低内存占用
Nginx 采用异步、非阻塞的事件驱动架构,能够在单台服务器上处理数以万计的并发连接,而内存消耗远低于传统的基于进程/线程的模型。
- 反向代理与负载均衡
作为反向代理,Nginx 可以将客户端请求分发到后端服务器(如应用服务器、数据库),并支持多种负载均衡算法(轮询、最少连接、IP 哈希等),实现高可用和水平扩展。
- 静态文件服务
Nginx 在处理静态文件(HTML、CSS、JavaScript、图片等)方面非常高效,能够直接发送文件而不占用过多的内存和 CPU。
- SSL/TLS 终止
支持 HTTP/2、HTTPS,可以集中管理 SSL 证书,对后端服务透明,减轻后端服务的加密负担。
- 缓存机制
内置强大的缓存功能,可以缓存后端响应,加速内容分发,降低后端压力。
- 模块化设计
核心功能精简,通过模块扩展。官方提供了丰富的模块(如 ngx_http_proxy_module、ngx_http_ssl_module),也支持第三方模块。
- 高可靠性
主进程与工作进程分离,主进程负责管理,工作进程处理请求。即使某个工作进程崩溃,主进程也能立即启动新的工作进程,保证服务持续可用。
0.2 架构解析
Nginx 的架构基于 事件驱动(event-driven) 和 非阻塞(non-blocking) 模型,具体实现依赖于操作系统的高效机制(如 Linux 的 epoll、FreeBSD 的 kqueue)。其进程模型如下:
- Master 进程:负责读取配置文件、绑定端口、启动和监控 Worker 进程。不处理具体请求。
- Worker 进程:通常每个 CPU 核心对应一个 Worker 进程。Worker 进程接受连接、处理请求,通过事件循环来管理多个连接。
每个 Worker 进程可以处理成千上万个连接,因为它通过事件通知机制在单个线程中处理所有并发 I/O 操作,而不是为每个连接创建独立的进程/线程。
这种设计使得 Nginx 在处理大量长连接(如 WebSocket、HTTP/2)时表现出色。
1.什么是反向代理?
在搞清楚反向代理之前,我们了解一下正向代理。
所谓正向代理,就是当用户访问原本无法访问网站A(比如google)时,我们首先通过某个代理服务器或某个代理池充当中介从而隐藏自己真实的ip,同时因为“中介”能够直接访问网站A,所以我们可以间接地访问到网站A。生活中常见的类似例子有路由器转发、开代理池的编程、缓存、上网行为认证等。
那么反向代理是什么呢?简单来说,就是当出差在外的用户突然需要访问单位A(比如学校)的内网时,必须先经过该单位的内部代理服务器,进而转发需要传达的消息到内部的后端服务器,从而使得学校内部或公司内部的相关人员接受到准确的消息。什么时候需要用到反向代理呢?其中一个好处是当一个公司同时部署了多个服务器时,对于发送的指定消息只需要访问其中一个或少量服务器时,如果没有反向代理服务器,在公网上这些消息无法确定被发送到那个服务器,从而造成大量的浪费资源的行为。但是,如果拥有反向代理服务器,这时候被指定的消息可能需要通过内部代理服务器来进行简单的转发从而达到负载均衡的目的。否则,当内部人员的消息内容过多或者来自外部的攻击行为过于频繁,这时候多个服务器可能面临瘫痪、崩溃的局面。例外一个好处就是,当使用Ngnix/Lua等反向代理技术时,这些内部服务器无法暴露在公网上,很好的隐藏了自己的真实ip,从而公网用户无法攻击内部服务器。同时利用反向代理技术可以迅速有效地部署防火墙产品,譬如AWS、GCP、宝塔、雷池等,这些防火墙有效地保护了个人数字资产。
总结来说,就正如前面的表格比较和下方文字描述的那样。
2.常见的配置模块
这些常用模块都是由ai画图软件总结的,大家阅读的时候可能对英语阅读能力较强,笔者建议读者结合官方文档做一个参考。
2.1 SSL/TLS证书模块
- server {
- listen 443 ssl http2;
- server_name example.com;
- # SSL Certificate files
- ssl_certificate /etc/nginx/ssl/example.com.crt;
- ssl_certificate_key /etc/nginx/ssl/example.com.key;
- # SSL Protocols and Ciphers
- ssl_protocols TLSv1.2 TLSv1.3;
- ssl_ciphers HIGH:!aNULL:!MD5;
- ssl_prefer_server_ciphers on;
- # SSL Session Cache
- ssl_session_cache shared:SSL:10m;
- ssl_session_timeout 10m;
- # HSTS (HTTP Strict Transport Security)
- add_header Strict-Transport-Security "max-age=31536000" always;
- location / {
- proxy_pass http://backend;
- }
- }
复制代码 2.2 gzip on 模块
- http {
- # Enable Gzip compression
- gzip on;
- gzip_vary on;
- gzip_proxied any;
- gzip_comp_level 6;
- gzip_min_length 1000;
- # Specify MIME types to compress
- gzip_types
- text/plain
- text/css
- text/xml
- text/javascript
- application/json
- application/javascript
- application/xml+rss
- application/rss+xml
- font/truetype
- font/opentype
- application/vnd.ms-fontobject
- image/svg+xml;
- # Disable gzip for IE6
- gzip_disable "msie6";
- server {
- listen 80;
- server_name example.com;
- # ... rest of config
- }
- }
复制代码 2.3 代理池模块
- upstream backend {
- server backend1.example.com:8080;
- server backend2.example.com:8080;
- server backend3.example.com:8080;
- }
- server {
- listen 80;
- server_name example.com;
- location / {
- # Basic proxy settings
- proxy_pass http://backend;
-
- # Headers
- 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;
- # Buffering
- proxy_buffering on;
- proxy_buffer_size 4k;
- proxy_buffers 8 4k;
- # Timeouts
- proxy_connect_timeout 60s;
- proxy_send_timeout 60s;
- proxy_read_timeout 60s;
- # Error handling
- proxy_next_upstream error timeout invalid_header http_500;
- }
- }
复制代码 2.4 重写模块
- server {
- listen 80;
- server_name example.com www.example.com;
- # Redirect www to non-www
- if ($host = www.example.com) {
- return 301 https://example.com$request_uri;
- }
- # Redirect HTTP to HTTPS
- return 301 https://$host$request_uri;
- }
- server {
- listen 443 ssl;
- server_name example.com;
- # Rewrite old URLs to new ones
- rewrite ^/old-page$ /new-page permanent;
- rewrite ^/blog/(.*)$ /articles/$1 permanent;
- # Conditional rewrites
- location /api {
- # Rewrite /api/v1/users to /users
- rewrite ^/api/v1/(.*)$ /$1 break;
- proxy_pass http://backend;
- }
- # Use try_files for clean URLs
- location / {
- try_files $uri $uri/ /index.html;
- }
- }
复制代码 2.5 响应头模块
- server {
- listen 80;
- server_name example.com;
- # Security Headers
- add_header X-Frame-Options "SAMEORIGIN" always;
- add_header X-Content-Type-Options "nosniff" always;
- add_header X-XSS-Protection "1; mode=block" always;
- add_header Referrer-Policy "no-referrer-when-downgrade" always;
- add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
- # Remove headers (for security)
- more_clear_headers 'Server';
- more_clear_headers 'X-Powered-By';
- # CORS Headers
- location /api {
- add_header Access-Control-Allow-Origin "*" always;
- add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
- add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
- if ($request_method = 'OPTIONS') {
- return 204;
- }
- proxy_pass http://backend;
- }
- # Cache Control
- location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
- expires 1y;
- add_header Cache-Control "public, immutable";
- }
- }
复制代码 2.6 速率限制模块
- http {
- # Define rate limit zones
- # Zone 'one' allows 10 requests per second per IP
- limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
-
- # Zone 'api' allows 100 requests per minute per IP
- limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;
-
- # Zone 'login' allows 5 requests per minute per IP
- limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
- server {
- listen 80;
- server_name example.com;
- # General rate limiting
- location / {
- limit_req zone=one burst=20 nodelay;
- proxy_pass http://backend;
- }
- # API rate limiting
- location /api {
- limit_req zone=api burst=50;
- limit_req_status 429;
- proxy_pass http://backend;
- }
- # Strict rate limiting for login
- location /login {
- limit_req zone=login burst=5;
- limit_req_log_level warn;
- proxy_pass http://backend;
- }
- }
- }
复制代码 2.7 镜像模块
- http {
- # Define cache path and settings
- proxy_cache_path /var/cache/nginx/data
- levels=1:2
- keys_zone=my_cache:10m
- max_size=1g
- inactive=60m
- use_temp_path=off;
- server {
- listen 80;
- server_name example.com;
- location / {
- # Enable caching
- proxy_cache my_cache;
-
- # Cache status in response header (for debugging)
- add_header X-Cache-Status $upstream_cache_status;
-
- # Cache valid responses
- proxy_cache_valid 200 302 10m;
- proxy_cache_valid 404 1m;
-
- # Cache even with certain headers
- proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
-
- # Cache locking
- proxy_cache_lock on;
- proxy_cache_lock_timeout 5s;
-
- # Cache key
- proxy_cache_key "$scheme$request_method$host$request_uri";
-
- # Bypass cache for certain conditions
- proxy_cache_bypass $http_pragma $http_authorization;
- proxy_no_cache $http_pragma $http_authorization;
- proxy_pass http://backend;
- }
- # Don't cache API POST requests
- location /api {
- proxy_cache_methods GET HEAD;
- proxy_pass http://backend;
- }
- }
- }
复制代码 2.8 基础认证模块
- server {
- listen 80;
- server_name example.com;
- # Protect entire site
- location / {
- auth_basic "Restricted Access";
- auth_basic_user_file /etc/nginx/.htpasswd;
- proxy_pass http://backend;
- }
- # Protect specific directory
- location /admin {
- auth_basic "Admin Area";
- auth_basic_user_file /etc/nginx/.htpasswd_admin;
- proxy_pass http://backend;
- }
- # Public location (no auth)
- location /public {
- auth_basic off;
- proxy_pass http://backend;
- }
- # Conditional authentication (IP-based)
- location /restricted {
- satisfy any;
-
- # Allow from specific IPs without password
- allow 192.168.1.0/24;
- allow 10.0.0.0/8;
- deny all;
-
- # Require password if not from allowed IP
- auth_basic "Restricted Access";
- auth_basic_user_file /etc/nginx/.htpasswd;
-
- proxy_pass http://backend;
- }
- }
- # Create password file with:
- # htpasswd -c /etc/nginx/.htpasswd username
复制代码 2.9 geoIP 模块
- http {
- # Define geo-based variables
- geo $country {
- default ZZ;
-
- # US IP ranges
- 1.2.3.0/24 US;
- 5.6.7.0/24 US;
-
- # UK IP ranges
- 10.20.30.0/24 UK;
-
- # Include external file
- include /etc/nginx/geo.conf;
- }
- # Create blocking rules based on country
- geo $blocked_country {
- default 0;
- 1.2.3.0/24 1; # Block this range
- }
- # Map based on geo
- map $country $redirect_domain {
- default example.com;
- US us.example.com;
- UK uk.example.com;
- DE de.example.com;
- }
- server {
- listen 80;
- server_name example.com;
- # Block specific countries
- if ($blocked_country) {
- return 403 "Access denied from your location";
- }
- # Redirect based on country
- location / {
- # Use country in headers
- add_header X-Country-Code $country;
-
- # Country-specific content
- root /var/www/$country;
- try_files $uri $uri/ /index.html;
- }
- # API endpoint that logs country
- location /api {
- proxy_set_header X-Country $country;
- proxy_pass http://backend;
- }
- }
- }
复制代码 2.10 upstream模块
- http {
- # Round-robin load balancing (default)
- upstream backend_round_robin {
- server backend1.example.com:8080;
- server backend2.example.com:8080;
- server backend3.example.com:8080;
- }
- # Least connections load balancing
- upstream backend_least_conn {
- least_conn;
-
- server backend1.example.com:8080;
- server backend2.example.com:8080;
- server backend3.example.com:8080;
- }
- # IP hash (session persistence)
- upstream backend_ip_hash {
- ip_hash;
-
- server backend1.example.com:8080;
- server backend2.example.com:8080;
- server backend3.example.com:8080;
- }
- # Weighted load balancing
- upstream backend_weighted {
- server backend1.example.com:8080 weight=3;
- server backend2.example.com:8080 weight=2;
- server backend3.example.com:8080 weight=1;
- }
- # Advanced configuration
- upstream backend_advanced {
- least_conn;
-
- # Primary servers
- 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;
-
- # Backup server (used when primary servers are down)
- server backup.example.com:8080 backup;
-
- # Keep alive connections
- keepalive 32;
- keepalive_timeout 60s;
- }
- server {
- listen 80;
- server_name example.com;
- location / {
- proxy_pass http://backend_advanced;
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- }
- }
- }
复制代码 3.常见的配置错误
3.1 错误的分号
- server {
- listen 80
- server_name example.com
-
- location / {
- proxy_pass http://backend
- }
- }
- server {
- listen 80;
- server_name example.com;
-
- location / {
- proxy_pass http://backend;
- }
- }
复制代码 3.2 错误的if 声明
- location / {
- # WRONG: Using if for redirects
- if ($request_uri ~* "^/old-url") {
- proxy_pass http://backend;
- }
-
- # WRONG: Multiple conditions
- if ($host != "example.com") {
- rewrite ^ https://example.com$request_uri permanent;
- }
- }
- # RIGHT: Use return for redirects
- location = /old-url {
- return 301 /new-url;
- }
- # RIGHT: Use separate server block
- server {
- listen 80;
- server_name www.example.com;
- return 301 https://example.com$request_uri;
- }
- server {
- listen 80;
- server_name example.com;
- # ... normal config
- }
复制代码 3.3 错误的尾部斜杠传递
- # This keeps the /api prefix
- location /api {
- proxy_pass http://backend; # Wrong if you want to strip /api
- }
- # This might cause double slashes
- location /api/ {
- proxy_pass http://backend/; # Creates //api/endpoint
- }
- # Strip /api prefix from request
- location /api/ {
- proxy_pass http://backend/; # /api/users -> /users
- }
- # Keep /api prefix in request
- location /api {
- proxy_pass http://backend; # /api/users -> /api/users
- }
- # Rewrite to remove prefix
- location /api {
- rewrite ^/api/(.*)$ /$1 break;
- proxy_pass http://backend;
- }
复制代码 3.4 缺失根目录与别名理解
- # WRONG: Using root when alias is needed
- location /static {
- root /var/www/assets; # Looks for /var/www/assets/static
- }
- # WRONG: Using alias without trailing slash
- location /images {
- alias /var/www/pics; # Should have trailing slash
- }
- # RIGHT: Using root (appends location to path)
- location /static {
- root /var/www; # Serves /var/www/static
- }
- # RIGHT: Using alias (replaces location in path)
- location /static {
- alias /var/www/assets/; # Serves /var/www/assets/
- }
- # Alternative with root
- location /static {
- root /var/www;
- # Serves /var/www/static/
- }
复制代码 3.5 重复的请求头
- http {
- add_header X-Frame-Options "DENY";
-
- server {
- add_header X-Frame-Options "SAMEORIGIN"; # Duplicate!
-
- location / {
- add_header X-Custom-Header "value";
- proxy_pass http://backend;
- # Header won't be added because proxy_pass clears headers
- }
- }
- }
- http {
- # Don't add headers here unless needed globally
-
- server {
- # Use 'always' to add headers even for error responses
- add_header X-Frame-Options "SAMEORIGIN" always;
- add_header X-Content-Type-Options "nosniff" always;
-
- location / {
- # Headers in location are inherited
- proxy_pass http://backend;
- # Add location-specific headers
- add_header X-Custom-Header "value" always;
- }
- }
- }
复制代码 3.6 错误的正则表达式
- # Case-sensitive match (might miss .JPG, .PNG)
- location ~ \.(jpg|png|gif)$ {
- expires 30d;
- }
- # Wrong: Using = with regex
- location = ~ /api {
- proxy_pass http://backend;
- }
- # Case-insensitive match for file extensions
- location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
- expires 30d;
- add_header Cache-Control "public, immutable";
- }
- # Exact match (fastest)
- location = /api {
- proxy_pass http://backend;
- }
- # Regex match (case-sensitive)
- location ~ ^/api/v[0-9]+ {
- proxy_pass http://backend;
- }
- # Regex match (case-insensitive)
- location ~* ^/API {
- proxy_pass http://backend;
- }
复制代码 3.7 错误的缓冲区大小
- location / {
- # Too small buffers
- proxy_buffer_size 1k;
- proxy_buffers 4 1k;
-
- # Inconsistent sizes
- client_body_buffer_size 128k;
- client_max_body_size 1m; # Should be larger
- }
- http {
- # Appropriate buffer sizes
- client_body_buffer_size 128k;
- client_max_body_size 10m;
- client_header_buffer_size 1k;
- large_client_header_buffers 4 8k;
- }
- location / {
- # Proxy buffer configuration
- proxy_buffering on;
- proxy_buffer_size 4k;
- proxy_buffers 8 4k;
- proxy_busy_buffers_size 8k;
-
- proxy_pass http://backend;
- }
复制代码 3.8 服务器名称哈希桶大小
[code]http { # Missing hash bucket size with many server names server { server_name example.com www.example.com api.example.com cdn.example.com static.example.com; } server { server_name another-very-long-domain-name.com www.another-very-long-domain-name.com; }}# Nginx may fail to start with error about hash bucket sizehttp { # Set appropriate hash bucket size server_names_hash_bucket_size 64; server_names_hash_max_size 512; server { server_name example.com www.example.com api.example.com cdn.example.com static.example.com; # ... config } server { server_name another-very-long-domain-name.com www.another-very-long-domain-name.com; # ... config }}**
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |