乐闻世界logo
搜索文章和话题

Nginx

Nginx 是一个网络和代理服务器。Nginx (发音为 "engine-x") 是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3 代理服务器。Nginx 是由 Igor Sysoev 开发的,最初发布于2004年,旨在解决 C10k 问题,即同时处理大量客户端连接的需求。由于其高性能、稳定性、丰富的功能集以及低资源消耗,Nginx 在全球范围内广泛用于提供网页内容,特别是在高流量的网站中非常流行。
Nginx
查看更多相关内容
Nginx 如何优化静态资源?有哪些优化策略?## Nginx 如何优化静态资源?有哪些优化策略? Nginx 在提供静态资源方面表现优异,通过合理的配置可以显著提升静态资源的加载速度和用户体验。 ### 启用高效文件传输: ```nginx http { # 启用 sendfile sendfile on; # 启用 tcp_nopush tcp_nopush on; # 启用 tcp_nodelay tcp_nodelay on; server { listen 80; server_name example.com; root /var/www/html; location / { try_files $uri $uri/ =404; } } } ``` ### Gzip 压缩: ```nginx http { # 启用 Gzip gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml application/atom+xml image/svg+xml; gzip_disable "msie6"; # 静态资源预压缩 gzip_static on; server { listen 80; server_name example.com; root /var/www/html; location / { try_files $uri $uri/ =404; } } } ``` ### 浏览器缓存: ```nginx server { listen 80; server_name example.com; root /var/www/html; # 静态资源长期缓存 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # HTML 文件短期缓存 location ~* \.html$ { expires 1h; add_header Cache-Control "public, must-revalidate"; } # 不缓存动态内容 location ~* \.php$ { expires off; add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; } location / { try_files $uri $uri/ =404; } } ``` ### 文件缓存: ```nginx http { # 打开文件缓存 open_file_cache max=100000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; server { listen 80; server_name example.com; root /var/www/html; location / { try_files $uri $uri/ =404; } } } ``` ### 静态资源分离: ```nginx server { listen 80; server_name example.com; # 主站点 location / { root /var/www/html; try_files $uri $uri/ =404; } # 静态资源 location /static/ { root /var/www/static; expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # 图片资源 location /images/ { root /var/www/images; expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # 字体文件 location /fonts/ { root /var/www/fonts; expires 1y; add_header Cache-Control "public, immutable"; access_log off; add_header Access-Control-Allow-Origin *; } } ``` ### CDN 集成: ```nginx server { listen 80; server_name example.com; root /var/www/html; # 重写静态资源 URL 到 CDN location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { return 301 https://cdn.example.com$request_uri; } location / { try_files $uri $uri/ =404; } } ``` ### 图片优化: ```nginx server { listen 80; server_name example.com; root /var/www/html; # 图片缓存 location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; # WebP 支持 if ($http_accept ~* "webp") { rewrite ^(.+)\.(jpg|png)$ $1.webp last; } } # 图片防盗链 location ~* \.(jpg|jpeg|png|gif)$ { valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; } } location / { try_files $uri $uri/ =404; } } ``` ### 字体文件优化: ```nginx server { listen 80; server_name example.com; root /var/www/html; # 字体文件 location ~* \.(woff|woff2|ttf|otf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; # CORS 支持 add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods "GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, Content-Type"; } location / { try_files $uri $uri/ =404; } } ``` ### 静态资源预加载: ```nginx server { listen 80; server_name example.com; root /var/www/html; location = / { add_header Link "</style.css>; rel=preload; as=style, </script.js>; rel=preload; as=script, </image.jpg>; rel=preload; as=image"; try_files $uri $uri/ =404; } location / { try_files $uri $uri/ =404; } } ``` ### HTTP/2 推送: ```nginx server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; root /var/www/html; # HTTP/2 推送 location = / { http2_push /style.css; http2_push /script.js; http2_push /image.jpg; try_files $uri $uri/ =404; } location / { try_files $uri $uri/ =404; } } ``` ### 静态资源合并: ```nginx # 使用第三方模块 ngx_http_concat_module server { listen 80; server_name example.com; root /var/www/html; # CSS 合并 location /static/css/ { concat on; concat_types text/css; concat_unique on; concat_max_files 10; } # JS 合并 location /static/js/ { concat on; concat_types application/javascript; concat_unique on; concat_max_files 10; } location / { try_files $uri $uri/ =404; } } ``` ### 完整静态资源优化配置: ```nginx user nginx; worker_processes auto; worker_rlimit_nofile 65535; events { worker_connections 10240; use epoll; multi_accept on; } http { # 基础优化 sendfile on; tcp_nopush on; tcp_nodelay on; # Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml application/atom+xml image/svg+xml; gzip_disable "msie6"; gzip_static on; # 文件缓存 open_file_cache max=100000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; # 静态资源长期缓存 map $sent_http_content_type $expires { default off; text/html 1h; text/css 1y; application/javascript 1y; ~image/ 1y; ~font/ 1y; } server { listen 80; server_name example.com; root /var/www/html; index index.html; # 静态资源优化 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires $expires; add_header Cache-Control "public, immutable"; access_log off; } # 字体文件 CORS location ~* \.(woff|woff2|ttf|otf|eot)$ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods "GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, Content-Type"; } # 图片防盗链 location ~* \.(jpg|jpeg|png|gif)$ { valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; } } # 主路由 location / { try_files $uri $uri/ =404; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } } } ``` ### 静态资源优化最佳实践: 1. **启用压缩**:使用 Gzip 压缩文本资源 2. **合理缓存**:根据资源类型设置缓存时间 3. **文件分离**:将静态资源分离到独立域名或 CDN 4. **预压缩**:使用 gzip_static 预压缩静态文件 5. **HTTP/2**:启用 HTTP/2 提升加载速度 6. **图片优化**:使用 WebP 格式,启用图片压缩 7. **字体优化**:使用 WOFF2 格式,启用 CORS 8. **监控性能**:使用 Lighthouse 等工具监控性能 9. **定期清理**:清理未使用的静态资源 10. **版本控制**:使用文件名哈希实现缓存更新
服务端 · 2月21日 16:58
Nginx 如何处理动态内容?有哪些配置方式?## Nginx 如何处理动态内容?有哪些配置方式? Nginx 本身不处理动态内容,而是通过 FastCGI、uWSGI、SCGI 等协议将请求转发给后端应用服务器处理。 ### FastCGI 配置(PHP): ```nginx server { listen 80; server_name example.com; root /var/www/html; index index.php index.html; # PHP 文件处理 location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; # FastCGI 参数 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; include fastcgi_params; # 超时设置 fastcgi_connect_timeout 60s; fastcgi_send_timeout 60s; fastcgi_read_timeout 60s; # 缓冲区设置 fastcgi_buffer_size 4k; fastcgi_buffers 8 4k; } location / { try_files $uri $uri/ /index.php?$query_string; } } ``` ### uWSGI 配置(Python): ```nginx upstream django_backend { server unix:/var/run/uwsgi/app.sock; server 127.0.0.1:8000; } server { listen 80; server_name example.com; root /var/www/html; location / { uwsgi_pass django_backend; include uwsgi_params; # uWSGI 参数 uwsgi_param UWSGI_SCHEME $scheme; uwsgi_param SERVER_NAME $server_name; uwsgi_param REMOTE_ADDR $remote_addr; # 超时设置 uwsgi_connect_timeout 60s; uwsgi_send_timeout 60s; uwsgi_read_timeout 60s; # 缓冲区设置 uwsgi_buffering on; uwsgi_buffer_size 4k; uwsgi_buffers 8 4k; } # 静态文件 location /static/ { alias /var/www/html/static/; expires 1y; add_header Cache-Control "public, immutable"; } } ``` ### SCGI 配置(Ruby): ```nginx upstream rails_backend { server unix:/var/run/scgi/rails.sock; server 127.0.0.1:9000; } server { listen 80; server_name example.com; root /var/www/html; location / { scgi_pass rails_backend; include scgi_params; # SCGI 参数 scgi_param SCGI 1; scgi_param SERVER_SOFTWARE nginx; # 超时设置 scgi_connect_timeout 60s; scgi_send_timeout 60s; scgi_read_timeout 60s; } } ``` ### HTTP 代理配置: ```nginx upstream nodejs_backend { server 127.0.0.1:3000; server 127.0.0.1:3001; } server { listen 80; server_name example.com; location / { proxy_pass http://nodejs_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; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 缓冲区设置 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ``` ### FastCGI 缓存: ```nginx # 定义 FastCGI 缓存 fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:10m max_size=1g inactive=60m; server { listen 80; server_name example.com; root /var/www/html; location ~ \.php$ { try_files $uri =404; # 启用 FastCGI 缓存 fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_valid 404 1m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; # 缓存跳过条件 fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 添加缓存状态头 add_header X-Cache-Status $upstream_cache_status; } } ``` ### 动态内容负载均衡: ```nginx upstream php_backend { least_conn; server 192.168.1.100:9000 weight=3; server 192.168.1.101:9000 weight=2; server 192.168.1.102:9000 weight=1; keepalive 32; } server { listen 80; server_name example.com; root /var/www/html; location ~ \.php$ { fastcgi_pass php_backend; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } ``` ### 动态内容压缩: ```nginx http { # 启用 Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml application/rss+xml; server { listen 80; server_name example.com; root /var/www/html; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } } ``` ### 动态内容安全: ```nginx server { listen 80; server_name example.com; root /var/www/html; # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; } # PHP 文件处理 location ~ \.php$ { # 防止 PHP 文件上传执行 if ($request_filename ~* \.(jpg|jpeg|png|gif|ico)$) { return 403; } fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 限制请求大小 client_max_body_size 10m; } location / { try_files $uri $uri/ /index.php?$query_string; } } ``` ### 动态内容监控: ```nginx # 自定义日志格式 log_format dynamic '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time" ' 'cache=$upstream_cache_status'; server { listen 80; server_name example.com; root /var/www/html; access_log /var/log/nginx/dynamic.log dynamic; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 添加性能头 add_header X-Response-Time $request_time; add_header X-Upstream-Time $upstream_response_time; } } ``` ### 完整动态内容配置示例: ```nginx user nginx; worker_processes auto; http { # FastCGI 缓存 fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:10m max_size=1g inactive=60m; # Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml application/rss+xml; # 日志格式 log_format dynamic '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time" ' 'cache=$upstream_cache_status'; # PHP 后端 upstream php_backend { least_conn; server 192.168.1.100:9000; server 192.168.1.101:9000; keepalive 32; } server { listen 80; server_name example.com; root /var/www/html; index index.php index.html; access_log /var/log/nginx/example.com.access.log dynamic; error_log /var/log/nginx/example.com.error.log warn; # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; } # 静态资源 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # PHP 文件处理 location ~ \.php$ { try_files $uri =404; # 启用缓存 fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_valid 404 1m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_pass php_backend; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; # 超时设置 fastcgi_connect_timeout 60s; fastcgi_send_timeout 60s; fastcgi_read_timeout 60s; # 缓冲区设置 fastcgi_buffer_size 4k; fastcgi_buffers 8 4k; # 添加缓存状态头 add_header X-Cache-Status $upstream_cache_status; add_header X-Response-Time $request_time; add_header X-Upstream-Time $upstream_response_time; } # 主路由 location / { try_files $uri $uri/ /index.php?$query_string; } } } ``` ### 动态内容处理最佳实践: 1. **使用缓存**:启用 FastCGI 缓存减少后端负载 2. **负载均衡**:使用 upstream 实现负载均衡 3. **合理超时**:根据业务需求设置超时时间 4. **缓冲区优化**:调整缓冲区大小提升性能 5. **压缩响应**:启用 Gzip 压缩减少传输数据 6. **安全配置**:防止文件上传执行和敏感文件访问 7. **监控性能**:记录响应时间和缓存命中率 8. **静态分离**:将静态资源分离到独立路径 9. **连接保持**:使用 keepalive 减少连接开销 10. **错误处理**:配置友好的错误页面
服务端 · 2月21日 16:58
Nginx 如何配置日志?有哪些日志格式和优化方法?## Nginx 如何配置日志?有哪些日志格式和优化方法? Nginx 日志对于监控、调试和安全审计非常重要。合理配置日志可以帮助快速定位问题和优化性能。 ### 访问日志配置: ```nginx http { # 自定义日志格式 log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time'; # 详细日志格式 log_format detailed '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time ' '$upstream_addr $upstream_status ' '$http_x_forwarded_for $request_id'; # JSON 格式日志 log_format json_combined 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",' '"http_referrer":"$http_referer",' '"http_user_agent":"$http_user_agent"' '}'; # 应用日志格式 access_log /var/log/nginx/access.log main; server { listen 80; server_name example.com; # 使用不同的日志格式 access_log /var/log/nginx/example.com.access.log detailed; location / { proxy_pass http://backend; } } } ``` ### 错误日志配置: ```nginx # 错误日志级别:debug, info, notice, warn, error, crit, alert, emerg error_log /var/log/nginx/error.log warn; # 不同级别的错误日志 error_log /var/log/nginx/error.log info; error_log /var/log/nginx/crit.log crit; ``` ### 日志优化: ```nginx http { # 禁用特定路径的日志 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { access_log off; } # 禁用健康检查日志 location /health { access_log off; return 200 "OK"; } # 缓冲日志写入 access_log /var/log/nginx/access.log main buffer=32k flush=5s; # 压缩日志 access_log /var/log/nginx/access.log main gzip=9; } ``` ### 条件日志记录: ```nginx http { # 根据状态码记录日志 map $status $loggable { ~^[23] 0; default 1; } # 根据请求方法记录日志 map $request_method $loggable_method { GET 1; POST 1; default 0; } server { listen 80; server_name example.com; # 只记录特定状态码的请求 access_log /var/log/nginx/access.log main if=$loggable; # 只记录特定方法的请求 access_log /var/log/nginx/method.log main if=$loggable_method; location / { proxy_pass http://backend; } } } ``` ### 分离日志: ```nginx http { # API 日志 log_format api '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time"'; server { listen 80; server_name example.com; # 主站点日志 access_log /var/log/nginx/main.log main; # API 日志 location /api/ { access_log /var/log/nginx/api.log api; proxy_pass http://api_backend; } # 静态资源不记录 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { access_log off; root /var/www/static; } } } ``` ### 日志轮转: ```bash # /etc/logrotate.d/nginx /var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 nginx adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript } ``` ### 日志分析变量: ```nginx log_format analysis '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time ' '$upstream_addr $upstream_status ' '$scheme $server_name $request_uri ' '$http_host $http_x_forwarded_for ' '$request_id $connection $connections ' '$time_iso8601 $msec'; ``` ### 常用日志变量: | 变量 | 说明 | |------|------| | $remote_addr | 客户端 IP 地址 | | $remote_user | 认证用户名 | | $time_local | 本地时间 | | $request | 完整的请求行 | | $status | 响应状态码 | | $body_bytes_sent | 发送的字节数 | | $http_referer | 来源页面 | | $http_user_agent | 用户代理 | | $request_time | 请求处理时间 | | $upstream_response_time | 上游响应时间 | | $upstream_addr | 上游服务器地址 | | $upstream_status | 上游状态码 | | $request_id | 请求 ID | | $http_x_forwarded_for | 真实客户端 IP | ### 日志监控和告警: ```nginx # 自定义错误日志格式 log_format error_log_format '$time_local [$level] $message'; # 记录慢请求 log_format slow_request '$remote_addr - $remote_user [$time_local] ' '"$request" $status $request_time ' 'upstream_response_time=$upstream_response_time'; http { # 慢请求阈值 map $request_time $slow_request { default 0; ~^([1-9]\d*\.?\d*|0\.\d*[1-9]\d*) 1; } server { listen 80; server_name example.com; # 记录慢请求 access_log /var/log/nginx/slow.log slow_request if=$slow_request; location / { proxy_pass http://backend; } } } ``` ### 日志安全: ```nginx http { # 不记录敏感信息 log_format secure '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time'; server { listen 80; server_name example.com; # 不记录密码等敏感信息 location /login { access_log /var/log/nginx/login.log secure; proxy_pass http://auth_backend; } # 不记录敏感路径 location ~* ^/(admin|api/v1/users) { access_log /var/log/nginx/sensitive.log secure; proxy_pass http://backend; } } } ``` ### 完整日志配置示例: ```nginx user nginx; worker_processes auto; http { # 日志格式 log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time'; log_format api '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time" ' 'upstream_addr=$upstream_addr upstream_status=$upstream_status'; log_format json_combined 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",' '"http_referrer":"$http_referer",' '"http_user_agent":"$http_user_agent",' '"upstream_response_time":"$upstream_response_time"' '}'; # 全局日志 access_log /var/log/nginx/access.log main buffer=32k flush=5s; error_log /var/log/nginx/error.log warn; # 条件日志 map $status $loggable { ~^[23] 0; default 1; } # 慢请求 map $request_time $slow_request { default 0; ~^([1-9]\d*\.?\d*|0\.\d*[1-9]\d*) 1; } server { listen 80; server_name example.com; # 主日志 access_log /var/log/nginx/example.com.access.log main if=$loggable; # 慢请求日志 access_log /var/log/nginx/slow.log main if=$slow_request; # API 日志 location /api/ { access_log /var/log/nginx/api.log api; proxy_pass http://api_backend; } # 静态资源不记录 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { access_log off; root /var/www/static; } # 健康检查不记录 location /health { access_log off; return 200 "OK"; } 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; } } } ``` ### 日志分析工具: 1. **GoAccess**:实时日志分析 2. **AWStats**:Web 日志分析 3. **ELK Stack**:Elasticsearch + Logstash + Kibana 4. **Grafana + Loki**:日志监控和可视化 5. **Splunk**:企业级日志分析 ### 日志优化建议: 1. **合理设置日志级别**:生产环境使用 warn 或 error 2. **使用缓冲**:减少磁盘 I/O 3. **定期轮转**:避免日志文件过大 4. **压缩旧日志**:节省磁盘空间 5. **分离日志**:按业务类型分离 6. **条件记录**:只记录必要的信息 7. **使用 JSON 格式**:便于机器解析 8. **监控日志大小**:防止磁盘占满
服务端 · 2月21日 16:57
Nginx 如何配置反向代理?## Nginx 如何配置反向代理? Nginx 反向代理是指 Nginx 服务器接收客户端请求,然后将请求转发到后端服务器,再将后端服务器的响应返回给客户端。客户端只知道 Nginx 服务器的存在,不知道实际处理请求的后端服务器。 ### 基本配置示例: ```nginx server { listen 80; server_name example.com; location / { proxy_pass http://backend_server; 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 { server 192.168.1.100:8080; server 192.168.1.101:8080; } ``` ### 关键配置指令说明: 1. **proxy_pass**:指定后端服务器地址,可以是 IP 地址、域名或 upstream 组名 2. **proxy_set_header**:设置转发给后端服务器的请求头 - Host:保留原始请求的主机名 - X-Real-IP:记录客户端真实 IP - X-Forwarded-For:记录请求经过的代理链 - X-Forwarded-Proto:记录原始协议(http/https) 3. **upstream**:定义后端服务器组,实现负载均衡 ### 常用反向代理配置选项: ```nginx location /api/ { proxy_pass http://backend_api; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 缓冲设置 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; # WebSocket 支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 禁用重定向 proxy_redirect off; } ``` ### 负载均衡策略: 1. **轮询(默认)**:按顺序分配请求 2. **least_conn**:分配给活动连接数最少的服务器 3. **ip_hash**:根据客户端 IP 进行哈希分配,保证同一 IP 的请求到同一服务器 4. **least_time**:分配给响应时间最短的服务器(需要商业版) ### 实际应用场景: - 将请求转发到多个应用服务器 - 隐藏后端服务器真实 IP - 统一入口,简化客户端配置 - 实现 SSL 终止 - 缓存静态内容 - WebSocket 代理
服务端 · 2月21日 16:57
Nginx 如何配置 WebSocket 代理?## Nginx 如何配置 WebSocket 代理? WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。Nginx 可以作为 WebSocket 代理,将客户端的 WebSocket 连接转发到后端服务器。 ### 基本配置: ```nginx map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name example.com; location /ws { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $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_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } } ``` ### 关键配置说明: 1. **proxy_http_version 1.1**:WebSocket 需要 HTTP/1.1 协议 2. **Upgrade 和 Connection 头**:告诉 Nginx 这是一个 WebSocket 连接 3. **超时设置**:WebSocket 是长连接,需要设置较长的超时时间 ### 完整配置示例: ```nginx http { upstream websocket_backend { server 192.168.1.100:8080; server 192.168.1.101:8080; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name example.com; # WebSocket 代理 location /ws { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $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_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; # 禁用缓冲 proxy_buffering off; } # 普通请求 location / { proxy_pass http://backend; proxy_set_header Host $host; } } } ``` ### HTTPS WebSocket 配置: ```nginx server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; location /ws { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } } ``` ### WebSocket 负载均衡: ```nginx upstream websocket_backend { # 使用 ip_hash 保持会话 ip_hash; server 192.168.1.100:8080; server 192.168.1.101:8080; server 192.168.1.102:8080; } ``` ### 注意事项: 1. **会话保持**:WebSocket 连接需要保持到同一台后端服务器,使用 ip_hash 或 sticky 模块 2. **超时设置**:根据业务需求设置合适的超时时间 3. **缓冲**:WebSocket 实时通信需要禁用缓冲 4. **防火墙**:确保防火墙允许长连接 5. **负载均衡**:避免使用轮询策略,会导致连接中断 ### 性能优化: ```nginx # 增加 worker 连接数 events { worker_connections 4096; } # 调整 keepalive upstream websocket_backend { server 192.168.1.100:8080; keepalive 32; } # 优化 TCP 参数 location /ws { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # TCP 优化 proxy_socket_keepalive on; proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; } ``` ### 多路径 WebSocket: ```nginx # 不同路径转发到不同后端 location /chat/ws { proxy_pass http://chat_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } location /notification/ws { proxy_pass http://notification_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } ``` ### 监控和日志: ```nginx # 自定义日志格式 log_format websocket '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time"'; access_log /var/log/nginx/websocket_access.log websocket; # 监控连接数 location /nginx_status { stub_status on; access_log off; } ``` ### 故障排查: 1. **连接断开**:检查超时设置是否合理 2. **无法连接**:检查 Upgrade 和 Connection 头是否正确 3. **负载均衡问题**:使用 ip_hash 保持会话 4. **性能问题**:调整 worker_connections 和缓冲设置
服务端 · 2月21日 16:57
Nginx 如何配置 HTTPS 和 SSL 证书?## Nginx 如何配置 HTTPS 和 SSL 证书? Nginx 配置 HTTPS 需要使用 SSL 模块,通过配置 SSL 证书来启用加密通信。HTTPS 可以保护数据传输的安全性,防止数据被窃听或篡改。 ### 基本配置示例: ```nginx server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; location / { root /var/www/html; index index.html; } } ``` ### SSL 证书配置参数: ```nginx server { listen 443 ssl http2; server_name example.com; # 证书文件路径 ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; # SSL 协议版本 ssl_protocols TLSv1.2 TLSv1.3; # 加密套件 ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # SSL 会话缓存 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/nginx/ssl/chain.crt; # HSTS add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; } ``` ### HTTP 自动跳转 HTTPS: ```nginx server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; location / { root /var/www/html; } } ``` ### SSL 证书类型: 1. **自签名证书**:用于测试环境,不被浏览器信任 2. **免费证书**:如 Let's Encrypt,有效期 90 天,可自动续期 3. **商业证书**:由 CA 机构颁发,有效期通常为 1 年 ### Let's Encrypt 证书申请: 使用 Certbot 工具申请免费证书: ```bash # 安装 Certbot sudo apt-get install certbot python3-certbot-nginx # 申请证书并自动配置 Nginx sudo certbot --nginx -d example.com -d www.example.com # 只申请证书,不自动配置 sudo certbot certonly --nginx -d example.com ``` ### 证书续期: ```bash # 手动续期 sudo certbot renew # 自动续期(添加到 crontab) 0 0,12 * * * certbot renew --quiet ``` ### 安全配置建议: 1. 使用 TLS 1.2 或更高版本 2. 禁用弱加密套件 3. 启用 HSTS 防止降级攻击 4. 配置 OCSP Stapling 提高性能 5. 定期更新证书 6. 使用强密钥(至少 2048 位) 7. 启用 HTTP/2 提升性能 ### 性能优化: ```nginx # SSL 会话缓存 ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; # 启用 HTTP/2 listen 443 ssl http2; # SSL 缓冲区大小 ssl_buffer_size 4k; ``` ### 多域名证书配置: ```nginx server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/nginx/ssl/wildcard.crt; ssl_certificate_key /etc/nginx/ssl/wildcard.key; location / { root /var/www/html; } } ``` ### 证书链配置: 如果证书需要中间证书,需要将证书和中间证书合并: ```bash cat example.com.crt intermediate.crt > bundle.crt ``` 然后在 Nginx 配置中使用 bundle.crt: ```nginx ssl_certificate /etc/nginx/ssl/bundle.crt; ```
服务端 · 2月21日 16:57
Nginx 如何进行监控和运维?有哪些监控工具?## Nginx 如何进行监控和运维?有哪些监控工具? Nginx 的监控和运维对于保证服务稳定性和性能至关重要。合理的监控可以及时发现和解决问题。 ### 内置状态监控: ```nginx # 启用 stub_status 模块 server { listen 80; server_name localhost; location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } } ``` **状态信息说明**: - Active connections:当前活动连接数 - accepts:已接受的连接总数 - handled:已处理的连接总数 - requests:已处理的请求总数 - Reading:正在读取请求头的连接数 - Writing:正在发送响应的连接数 - Waiting:空闲连接数 ### 自定义监控端点: ```nginx server { listen 80; server_name localhost; # 健康检查 location /health { access_log off; return 200 "OK\n"; add_header Content-Type text/plain; } # 就绪检查 location /ready { access_log off; # 检查后端连接 proxy_pass http://backend/health; proxy_intercept_errors off; } # 版本信息 location /version { access_log off; return 200 "Nginx/1.21.0\n"; add_header Content-Type text/plain; } } ``` ### 日志监控: ```nginx # 自定义日志格式 log_format monitoring '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time" ' 'cache=$upstream_cache_status'; server { listen 80; server_name example.com; access_log /var/log/nginx/monitoring.log monitoring; location / { proxy_pass http://backend; } } ``` ### Prometheus 监控: ```nginx # 安装 nginx-prometheus-exporter # https://github.com/nginxinc/nginx-prometheus-exporter # 配置 Nginx server { listen 80; server_name localhost; location /metrics { proxy_pass http://localhost:9113/metrics; access_log off; allow 127.0.0.1; deny all; } } ``` ### Grafana + Prometheus 监控: ```yaml # prometheus.yml global: scrape_interval: 15s scrape_configs: - job_name: 'nginx' static_configs: - targets: ['localhost:9113'] ``` ### ELK Stack 监控: ```nginx # JSON 格式日志 log_format json_combined 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",' '"http_referrer":"$http_referer",' '"http_user_agent":"$http_user_agent"' '}'; server { listen 80; server_name example.com; access_log /var/log/nginx/access.log json_combined; location / { proxy_pass http://backend; } } ``` ### Zabbix 监控: ```bash # 安装 Zabbix Agent # 配置监控项 # nginx_status[accepts] # nginx_status[handled] # nginx_status[requests] # nginx_status[reading] # nginx_status[writing] # nginx_status[waiting] ``` ### 性能监控指标: ```nginx # 启用详细日志 log_format performance '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' 'rt=$request_time ' 'uct=$upstream_connect_time ' 'uht=$upstream_header_time ' 'urt=$upstream_response_time ' 'cache=$upstream_cache_status'; server { listen 80; server_name example.com; access_log /var/log/nginx/performance.log performance; location / { proxy_pass http://backend; } } ``` ### 告警配置: ```nginx # 基于日志的告警 map $status $alert_level { ~^[5] critical; ~^[4] warning; default ok; } server { listen 80; server_name example.com; access_log /var/log/nginx/access.log performance; location / { proxy_pass http://backend; # 添加告警头 add_header X-Alert-Level $alert_level; } } ``` ### 自动化运维脚本: ```bash #!/bin/bash # nginx_monitor.sh # 检查 Nginx 状态 check_nginx_status() { if ! curl -f http://localhost/nginx_status > /dev/null 2>&1; then echo "Nginx status page is not accessible" return 1 fi return 0 } # 检查进程 check_nginx_process() { if ! pgrep -x nginx > /dev/null; then echo "Nginx process is not running" return 1 fi return 0 } # 检查端口 check_nginx_port() { if ! netstat -tlnp | grep :80 > /dev/null; then echo "Nginx is not listening on port 80" return 1 fi return 0 } # 主函数 main() { check_nginx_status check_nginx_process check_nginx_port echo "All checks passed" } main ``` ### 运维命令: ```bash # 重载配置(不中断服务) nginx -s reload # 优雅停止 nginx -s quit # 快速停止 nginx -s stop # 重新打开日志文件 nginx -s reopen # 测试配置 nginx -t # 查看版本 nginx -v # 查看编译参数 nginx -V ``` ### 日志轮转: ```bash # /etc/logrotate.d/nginx /var/log/nginx/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 nginx adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript } ``` ### 完整监控配置示例: ```nginx user nginx; worker_processes auto; http { # 日志格式 log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; log_format performance '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' 'rt=$request_time ' 'uct=$upstream_connect_time ' 'uht="$upstream_header_time" ' 'urt="$upstream_response_time" ' 'cache=$upstream_cache_status'; log_format json_combined 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",' '"http_referrer":"$http_referer",' '"http_user_agent":"$http_user_agent"' '}'; # 主站点 server { listen 80; server_name example.com; root /var/www/html; index index.html; # 性能日志 access_log /var/log/nginx/performance.log performance; error_log /var/log/nginx/error.log warn; # 监控端点 location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } location /health { access_log off; return 200 "OK\n"; add_header Content-Type text/plain; } location /ready { access_log off; proxy_pass http://backend/health; proxy_intercept_errors off; } location /metrics { proxy_pass http://localhost:9113/metrics; access_log off; allow 127.0.0.1; deny all; } 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; } } } ``` ### 监控工具推荐: 1. **Prometheus + Grafana**:强大的监控和可视化平台 2. **ELK Stack**:日志收集、存储和分析 3. **Zabbix**:企业级监控系统 4. **Nagios**:成熟的监控解决方案 5. **Datadog**:云端监控服务 6. **New Relic**:应用性能监控 7. **AppDynamics**:应用性能管理 ### 运维最佳实践: 1. **全面监控**:监控性能、日志、资源使用 2. **及时告警**:设置合理的告警阈值 3. **定期备份**:备份配置和重要数据 4. **自动化运维**:使用脚本和工具自动化运维 5. **文档记录**:详细记录运维操作和问题 6. **定期演练**:定期进行故障演练 7. **性能优化**:持续监控和优化性能 8. **安全审计**:定期进行安全检查 9. **容量规划**:根据业务增长进行容量规划 10. **持续改进**:根据监控数据持续改进
服务端 · 2月21日 16:57
Nginx 如何进行性能调优?有哪些关键参数?## Nginx 如何进行性能调优?有哪些关键参数? Nginx 性能调优是一个系统工程,需要从多个维度进行优化。合理的配置可以显著提升 Nginx 的处理能力和响应速度。 ### 核心配置优化: ```nginx # 全局配置 user nginx; worker_processes auto; # 自动设置为 CPU 核心数 worker_rlimit_nofile 100000; # 文件描述符限制 worker_cpu_affinity auto; # CPU 亲和性绑定 events { worker_connections 65535; # 每个 worker 的最大连接数 use epoll; # Linux 使用 epoll multi_accept on; # 同时接受多个连接 accept_mutex off; # 关闭互斥锁,减少锁竞争 } http { # 基础优化 sendfile on; # 启用高效文件传输 tcp_nopush on; # 优化数据包发送 tcp_nodelay on; # 禁用 Nagle 算法 keepalive_timeout 65; # 长连接超时 keepalive_requests 100; # 长连接最大请求数 # 缓冲区优化 client_body_buffer_size 128k; # 客户端请求体缓冲区 client_max_body_size 10m; # 最大请求体大小 client_header_buffer_size 1k; # 客户端请求头缓冲区 large_client_header_buffers 4 4k; # 大请求头缓冲区 # 输出缓冲 output_buffers 1 32k; # 输出缓冲区 postpone_output 1460; # 延迟输出 # 文件缓存 open_file_cache max=100000 inactive=20s; # 文件描述符缓存 open_file_cache_valid 30s; # 缓存验证间隔 open_file_cache_min_uses 2; # 最小使用次数 open_file_cache_errors on; # 缓存错误信息 # Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss; gzip_disable "msie6"; } ``` ### Worker 进程优化: ```nginx # 根据 CPU 核心数设置 worker_processes auto; # 绑定 CPU 核心(手动设置) # 假设 4 核 CPU worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000; # 设置工作进程优先级 worker_priority -5; # -20 到 19,数值越小优先级越高 ``` ### 连接优化: ```nginx events { # 增加连接数 worker_connections 65535; # 同时接受多个连接 multi_accept on; # 关闭互斥锁(高并发时) accept_mutex off; # 使用高效的事件模型 use epoll; # Linux # use kqueue; # BSD/macOS } http { # 长连接优化 keepalive_timeout 65; keepalive_requests 100; # 上游服务器长连接 upstream backend { server 192.168.1.100:8080; keepalive 32; # 保持 32 个空闲连接 } # 代理超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } ``` ### 缓冲区优化: ```nginx http { # 客户端缓冲区 client_body_buffer_size 128k; client_max_body_size 10m; client_header_buffer_size 1k; large_client_header_buffers 4 4k; # 代理缓冲区 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; # FastCGI 缓冲区 fastcgi_buffer_size 4k; fastcgi_buffers 8 4k; # 输出缓冲 output_buffers 1 32k; postpone_output 1460; } ``` ### 文件操作优化: ```nginx http { # 文件缓存 open_file_cache max=100000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; # 高效文件传输 sendfile on; tcp_nopush on; tcp_nodelay on; # 直接 I/O(大文件) # directio 4m; } ``` ### 压缩优化: ```nginx http { gzip on; gzip_vary on; gzip_min_length 1024; # 最小压缩文件大小 gzip_comp_level 6; # 压缩级别 1-9 gzip_buffers 16 8k; # 压缩缓冲区 gzip_http_version 1.1; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml application/atom+xml image/svg+xml; gzip_disable "msie6"; # 静态资源预压缩 gzip_static on; } ``` ### 日志优化: ```nginx http { # 自定义日志格式 log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time"'; # 访问日志 access_log /var/log/nginx/access.log main buffer=32k flush=5s; # 错误日志 error_log /var/log/nginx/error.log warn; # 关闭静态资源日志 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { access_log off; } } ``` ### SSL/TLS 优化: ```nginx server { listen 443 ssl http2; # SSL 会话缓存 ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; ssl_session_tickets off; # SSL 缓冲区 ssl_buffer_size 4k; # 协议和加密套件 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; } ``` ### 系统级优化: ```bash # /etc/sysctl.conf # 文件描述符 fs.file-max = 1000000 # TCP 参数 net.ipv4.tcp_max_tw_buckets = 6000 net.ipv4.tcp_sack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_rmem = 4096 87380 4194304 net.ipv4.tcp_wmem = 4096 65536 4194304 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.tcp_tw_reuse = 1 # 应用配置 sysctl -p ``` ### 用户限制: ```bash # /etc/security/limits.conf nginx soft nofile 65535 nginx hard nofile 65535 ``` ### 监控和诊断: ```nginx # 状态监控 location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } # 请求追踪 location /debug { add_header X-Request-ID $request_id; add_header X-Upstream-Addr $upstream_addr; } ``` ### 性能测试工具: ```bash # wrk 压力测试 wrk -t12 -c4000 -d30s http://example.com/ # ab 压力测试 ab -n 10000 -c 1000 http://example.com/ # siege 压力测试 siege -c 100 -t 60S http://example.com/ ``` ### 关键性能指标: 1. **QPS(每秒查询数)**:衡量处理能力 2. **响应时间**:平均、P95、P99 3. **并发连接数**:当前活动连接 4. **错误率**:4xx、5xx 错误比例 5. **CPU 使用率**:不应持续超过 70% 6. **内存使用**:监控内存占用 7. **磁盘 I/O**:监控读写性能 ### 调优建议: 1. **渐进式调优**:每次只调整一个参数,观察效果 2. **基准测试**:调优前后进行性能对比 3. **监控指标**:持续关注关键性能指标 4. **日志分析**:分析访问日志发现瓶颈 5. **定期审查**:定期检查配置是否合理
服务端 · 2月21日 16:57
Nginx 如何进行安全配置?有哪些安全最佳实践?## Nginx 如何进行安全配置?有哪些安全最佳实践? Nginx 的安全配置对于保护 Web 服务器免受各种攻击至关重要。合理的安全配置可以有效防止常见的安全威胁。 ### 基础安全配置: ```nginx # 隐藏 Nginx 版本号 server_tokens off; # 限制请求方法 if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 405; } # 限制请求体大小 client_max_body_size 10m; # 限制请求头大小 client_header_buffer_size 1k; large_client_header_buffers 4 4k; # 超时设置 client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; ``` ### 防止常见攻击: #### 1. 防止 SQL 注入: ```nginx location ~* \.(php|jsp|asp)$ { if ($args ~* "union.*select.*\(") { return 403; } if ($args ~* "concat.*\(") { return 403; } } ``` #### 2. 防止 XSS 攻击: ```nginx location ~* \.(php|html|htm)$ { if ($args ~* "<script>|</script>|javascript:|onerror=|onload=|onclick=") { return 403; } } ``` #### 3. 防止文件包含攻击: ```nginx location ~* \.(php|inc|config)$ { if ($args ~* "\.\./") { return 403; } } ``` #### 4. 防止目录遍历: ```nginx location ~* /\.\. { deny all; } ``` ### 访问控制: ```nginx # IP 白名单 location /admin { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; } # IP 黑名单 location / { deny 192.168.1.100; deny 192.168.1.101; allow all; } # 基本认证 location /admin { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; } ``` ### 防止 DDoS 攻击: ```nginx # 限制连接数 limit_conn_zone $binary_remote_addr zone=conn_limit:10m; server { limit_conn conn_limit 10; # 限制请求速率 limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; limit_req zone=req_limit burst=20 nodelay; # 限制带宽 limit_rate_after 10m; limit_rate 1m; } ``` ### SSL/TLS 安全配置: ```nginx server { listen 443 ssl http2; server_name example.com; # 证书配置 ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; # 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; ssl_prefer_server_ciphers on; # SSL 会话缓存 ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; ssl_session_tickets off; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/nginx/ssl/chain.crt; # HSTS add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # 其他安全头 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 "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always; } ``` ### 文件安全: ```nginx # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; log_not_found off; } # 禁止访问备份文件 location ~* \~$ { deny all; access_log off; log_not_found off; } # 禁止目录浏览 autoindex off; # 禁止访问特定目录 location ~* ^/(admin|config|backup|tmp)/ { deny all; } ``` ### 防止恶意 User-Agent: ```nginx # 阻止恶意爬虫 if ($http_user_agent ~* (bot|crawl|spider|scraper)) { return 403; } # 阻止特定 User-Agent if ($http_user_agent ~* (wget|curl|python-requests)) { return 403; } ``` ### 防止图片盗链: ```nginx location ~* \.(jpg|jpeg|png|gif|ico|svg)$ { valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; } } ``` ### 日志安全: ```nginx # 自定义日志格式,记录更多安全信息 log_format security '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time ' '$http_x_forwarded_for'; # 访问日志 access_log /var/log/nginx/access.log security; # 错误日志 error_log /var/log/nginx/error.log warn; # 敏感路径不记录日志 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { access_log off; } ``` ### 防止缓冲区溢出: ```nginx # 限制缓冲区大小 client_body_buffer_size 128k; client_header_buffer_size 1k; large_client_header_buffers 4 4k; client_max_body_size 10m; # 代理缓冲区 proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; ``` ### 安全最佳实践: 1. **定期更新**:保持 Nginx 和系统补丁最新 2. **最小权限原则**:使用非 root 用户运行 Nginx 3. **禁用不必要的模块**:减少攻击面 4. **配置防火墙**:限制不必要的端口访问 5. **使用 HTTPS**:启用 SSL/TLS 加密 6. **定期审计日志**:监控异常访问 7. **实施 WAF**:使用 Web 应用防火墙 8. **备份配置**:定期备份配置文件 9. **测试配置**:使用 `nginx -t` 测试配置 10. **监控性能**:使用监控工具跟踪性能指标 ### 完整安全配置示例: ```nginx user nginx; worker_processes auto; worker_rlimit_nofile 65535; # 隐藏版本号 server_tokens off; events { worker_connections 1024; use epoll; } http { # 基础安全 client_max_body_size 10m; client_header_buffer_size 1k; large_client_header_buffers 4 4k; # 超时设置 client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; # 限流 limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn_limit:10m; # 日志 log_format security '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; access_log /var/log/nginx/access.log security; error_log /var/log/nginx/error.log warn; # Gzip gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; server { listen 80; server_name example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com; # SSL 配置 ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:50m; ssl_session_timeout 1d; # 安全头 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # 限流 limit_req zone=req_limit burst=20 nodelay; limit_conn conn_limit 10; # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; } # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; } # 管理后台访问控制 location /admin { allow 192.168.1.0/24; deny all; auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } # 主站点 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; } } } ```
服务端 · 2月21日 16:57
Nginx 如何实现限流?有哪些限流策略?## Nginx 如何实现限流?有哪些限流策略? Nginx 提供了强大的限流功能,可以有效防止 DDoS 攻击、保护服务器资源、防止恶意请求。Nginx 的限流主要通过 `limit_req` 和 `limit_conn` 模块实现。 ### 请求速率限制(limit_req): ```nginx http { # 定义限流区域,基于客户端 IP limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; # 定义限流区域,基于请求 URI limit_req_zone $request_uri zone=uri:10m rate=5r/s; # 定义限流区域,基于服务器名称 limit_req_zone $server_name zone=server:10m rate=100r/s; server { listen 80; server_name example.com; # 应用限流 location / { limit_req zone=one burst=20 nodelay; proxy_pass http://backend; } # API 接口限流 location /api/ { limit_req zone=one burst=10 nodelay; limit_req_status 429; proxy_pass http://api_backend; } } } ``` ### 参数说明: 1. **limit_req_zone**:定义限流区域 - `$binary_remote_addr`:客户端 IP 地址(二进制格式,节省内存) - `zone=one:10m`:区域名称和共享内存大小(10M 可存储约 16 万个 IP) - `rate=10r/s`:每秒允许 10 个请求 2. **limit_req**:应用限流规则 - `zone=one`:使用的限流区域 - `burst=20`:允许的突发请求数 - `nodelay`:不延迟处理突发请求 3. **limit_req_status**:超过限制时返回的状态码(默认 503) ### 连接数限制(limit_conn): ```nginx http { # 定义连接数限制区域 limit_conn_zone $binary_remote_addr zone=addr:10m; # 定义服务器连接数限制区域 limit_conn_zone $server_name zone=server:10m; server { listen 80; server_name example.com; # 限制每个 IP 的并发连接数 limit_conn addr 10; # 限制服务器的总连接数 limit_conn server 1000; location / { proxy_pass http://backend; } } } ``` ### 带宽限制: ```nginx server { listen 80; server_name example.com; location /download/ { # 限制下载速度为 1MB/s limit_rate 1m; # 前 10MB 不限速 limit_rate_after 10m; root /var/www/files; } } ``` ### 综合限流配置: ```nginx http { # 请求速率限制 limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; limit_req_zone $request_uri zone=uri_limit:10m rate=5r/s; # 连接数限制 limit_conn_zone $binary_remote_addr zone=conn_limit:10m; # 状态码限制 limit_req_status 429; limit_conn_status 429; server { listen 80; server_name example.com; # 全局限流 limit_conn conn_limit 10; # 首页限流 location = / { limit_req zone=req_limit burst=20 nodelay; proxy_pass http://backend; } # API 接口严格限流 location /api/ { limit_req zone=req_limit burst=5 nodelay; limit_req zone=uri_limit burst=2 nodelay; proxy_pass http://api_backend; } # 下载限速 location /download/ { limit_rate 1m; limit_rate_after 10m; root /var/www/files; } # 静态资源不限流 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { root /var/www/static; } } } ``` ### 白名单配置: ```nginx http { # 定义限流区域 limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; # 定义白名单 geo $limit_key { default $binary_remote_addr; 192.168.1.0/24 ""; 10.0.0.0/8 ""; } # 基于白名单的限流 limit_req_zone $limit_key zone=whitelist_limit:10m rate=10r/s; server { listen 80; server_name example.com; location / { limit_req zone=whitelist_limit burst=20 nodelay; proxy_pass http://backend; } } } ``` ### 动态限流: ```nginx http { # 根据请求方法限流 map $request_method $limit_key { default $binary_remote_addr; GET ""; HEAD ""; } limit_req_zone $limit_key zone=dynamic_limit:10m rate=10r/s; server { listen 80; server_name example.com; location / { limit_req zone=dynamic_limit burst=20 nodelay; proxy_pass http://backend; } } } ``` ### 限流日志: ```nginx http { # 自定义日志格式,包含限流信息 log_format limit '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time limit=$limit_req_status'; access_log /var/log/nginx/access.log limit; # 限流区域 limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; server { listen 80; server_name example.com; location / { limit_req zone=req_limit burst=20 nodelay; limit_req_log_level warn; proxy_pass http://backend; } } } ``` ### 限流策略选择: 1. **固定窗口限流**:`rate=10r/s`,每秒固定请求数 2. **滑动窗口限流**:通过 burst 参数实现 3. **令牌桶算法**:Nginx 默认使用,允许突发流量 4. **漏桶算法**:通过 `nodelay` 参数控制 ### 实际应用场景: #### 1. API 接口限流: ```nginx limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/min; location /api/ { limit_req zone=api_limit burst=10 nodelay; limit_req_status 429; add_header X-RateLimit-Limit "100"; add_header X-RateLimit-Remaining "90"; add_header X-RateLimit-Reset "60"; proxy_pass http://api_backend; } ``` #### 2. 登录接口限流: ```nginx limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/min; location /login { limit_req zone=login_limit burst=2 nodelay; limit_req_status 429; proxy_pass http://auth_backend; } ``` #### 3. 文件下载限速: ```nginx location /download/ { limit_rate 500k; limit_rate_after 5m; root /var/www/files; } ``` #### 4. 防止暴力破解: ```nginx limit_req_zone $binary_remote_addr zone=auth_limit:10m rate=3r/min; location ~* ^/(login|register|reset-password) { limit_req zone=auth_limit burst=1 nodelay; limit_req_status 429; proxy_pass http://auth_backend; } ``` ### 监控和调试: ```nginx # 启用限流状态监控 location /limit_status { limit_req_status 429; add_header Content-Type text/plain; return 200 "Rate limit status: $limit_req_status"; } # 查看限流统计 location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } ``` ### 最佳实践: 1. **合理设置速率**:根据业务需求设置合理的限流速率 2. **使用 burst**:允许一定程度的突发流量 3. **返回友好错误**:设置 429 状态码,返回友好提示 4. **白名单机制**:对可信 IP 放开限流 5. **监控限流效果**:定期检查限流日志,调整策略 6. **分层限流**:对不同接口设置不同的限流策略 7. **结合缓存**:对静态资源使用缓存,减少限流压力 ### 性能考虑: 1. **共享内存大小**:根据 IP 数量合理设置 zone 大小 2. **限流粒度**:选择合适的限流键(IP、URI 等) 3. **日志级别**:生产环境使用 warn 级别,减少日志量 4. **nodelay 使用**:根据场景选择是否使用 nodelay
服务端 · 2月21日 16:57