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

面试题手册

Nginx 如何实现访问控制?有哪些访问控制方法?

Nginx 如何实现访问控制?有哪些访问控制方法?Nginx 提供了多种访问控制方法,包括基于 IP 的访问控制、基本认证、访问令牌等,可以有效保护敏感资源。IP 访问控制:server { listen 80; server_name example.com; # IP 白名单 location /admin { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; proxy_pass http://backend; } # IP 黑名单 location / { deny 192.168.1.100; deny 192.168.1.101; allow all; proxy_pass http://backend; }}基本认证:server { listen 80; server_name example.com; # 创建密码文件 # htpasswd -c /etc/nginx/.htpasswd username location /admin { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } # 多用户认证 location /api { auth_basic "API Access"; auth_basic_user_file /etc/nginx/.htpasswd_api; proxy_pass http://api_backend; }}访问令牌:server { listen 80; server_name example.com; # 基于 Header 的访问控制 location /api { if ($http_authorization !~* "Bearer .*") { return 401; } proxy_pass http://api_backend; } # 基于查询参数的访问控制 location /protected { if ($arg_token != "secret_token") { return 403; } proxy_pass http://backend; }}地理位置访问控制:http { # 定义地理位置映射 geo $allowed_country { default no; CN yes; US yes; } server { listen 80; server_name example.com; location / { if ($allowed_country = no) { return 403; } proxy_pass http://backend; } }}基于请求方法的访问控制:server { listen 80; server_name example.com; # 限制允许的请求方法 if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 405; } # 特定路径只允许特定方法 location /api { if ($request_method !~ ^(GET|POST)$ ) { return 405; } proxy_pass http://api_backend; } # 只读接口 location /api/read { if ($request_method !~ ^(GET|HEAD)$ ) { return 405; } proxy_pass http://api_backend; }}基于请求头的访问控制:server { listen 80; server_name example.com; # 检查特定的请求头 location /api { if ($http_x_api_key = "") { return 401; } proxy_pass http://api_backend; } # 检查 User-Agent location / { if ($http_user_agent ~* (bot|crawl|spider)) { return 403; } proxy_pass http://backend; } # 检查 Referer location /download { valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; } root /var/www/files; }}复杂访问控制:http { # 定义多个访问控制变量 geo $whitelist { default 0; 192.168.1.0/24 1; 10.0.0.0/8 1; } map $http_x_api_key $api_valid { default 0; "secret_key_123" 1; "secret_key_456" 1; } server { listen 80; server_name example.com; # 组合多个访问控制条件 location /admin { # IP 白名单 allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; # 基本认证 auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } # API 访问控制 location /api { # 检查 API Key if ($api_valid = 0) { return 401; } # 限制请求方法 if ($request_method !~ ^(GET|POST|PUT|DELETE)$ ) { return 405; } proxy_pass http://api_backend; } # 静态资源访问控制 location /protected { # IP 白名单或认证 satisfy any; allow 192.168.1.0/24; deny all; auth_basic "Protected Area"; auth_basic_user_file /etc/nginx/.htpasswd; root /var/www/protected; } }}基于时间的访问控制:http { # 定义时间段 map $time_iso8601 $business_hours { default 0; ~^(\d{4}-\d{2}-\d{2}T(09|1[0-9]|2[0-1])) 1; } server { listen 80; server_name example.com; # 只在工作时间允许访问 location /admin { if ($business_hours = 0) { return 403; } proxy_pass http://backend; } }}防止目录遍历:server { listen 80; server_name example.com; # 禁止访问父目录 location ~* /\.\. { deny all; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 禁止目录浏览 autoindex off; location / { proxy_pass http://backend; }}限制文件类型访问:server { listen 80; server_name example.com; # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; log_not_found off; } # 只允许特定文件类型 location /uploads { location ~* \.(jpg|jpeg|png|gif|pdf|doc|docx)$ { root /var/www/uploads; } location ~* \.(php|sh|exe|bat)$ { deny all; } }}访问控制最佳实践:最小权限原则:只授予必要的访问权限多层防护:组合使用多种访问控制方法定期审查:定期检查和更新访问控制规则日志记录:记录所有访问控制事件白名单优先:优先使用白名单而非黑名单测试配置:在生产环境前充分测试访问控制规则监控异常:监控异常访问行为及时更新:及时更新密码和访问令牌完整访问控制配置示例:http { # IP 白名单 geo $whitelist { default 0; 192.168.1.0/24 1; 10.0.0.0/8 1; } # API Key 验证 map $http_x_api_key $api_valid { default 0; "secret_key_123" 1; "secret_key_456" 1; } # 工作时间 map $time_iso8601 $business_hours { default 0; ~^(\d{4}-\d{2}-\d{2}T(09|1[0-9]|2[0-1])) 1; } server { listen 80; server_name example.com; # 管理后台 location /admin { # IP 白名单 allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; # 基本认证 auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; # 工作时间限制 if ($business_hours = 0) { return 403; } proxy_pass http://backend; } # API 接口 location /api { # API Key 验证 if ($api_valid = 0) { return 401; } # 限制请求方法 if ($request_method !~ ^(GET|POST|PUT|DELETE)$ ) { return 405; } # 限流 limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/min; limit_req zone=api_limit burst=10 nodelay; proxy_pass http://api_backend; } # 受保护资源 location /protected { # IP 白名单或认证 satisfy any; allow 192.168.1.0/24; deny all; auth_basic "Protected Area"; auth_basic_user_file /etc/nginx/.htpasswd; root /var/www/protected; } # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; log_not_found off; } # 禁止目录遍历 location ~* /\.\. { deny all; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 主站点 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; } }}
阅读 0·2月21日 16:57

Nginx 如何实现缓存?如何配置缓存策略?

Nginx 如何实现缓存?如何配置缓存策略?Nginx 提供了强大的缓存功能,可以缓存后端服务器的响应,减轻后端负载,提高响应速度。Nginx 支持代理缓存和 FastCGI 缓存等多种缓存方式。代理缓存配置:http { # 定义缓存路径和参数 proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy_cache:10m max_size=1g inactive=60m use_temp_path=off; server { listen 80; server_name example.com; location / { proxy_cache proxy_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_bypass $http_cache_control; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }}缓存参数说明:proxycachepath:定义缓存存储路径和参数levels:缓存目录层级结构keys_zone:共享内存区域名称和大小max_size:缓存最大大小inactive:缓存项不活动时间use_temp_path:是否使用临时路径proxy_cache:指定使用的缓存区域proxycachevalid:设置不同状态码的缓存时间200 302 10m:200 和 302 状态码缓存 10 分钟404 1m:404 状态码缓存 1 分钟proxycachekey:定义缓存键proxycachebypass:绕过缓存的条件FastCGI 缓存配置:http { 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; location ~ \.php$ { fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_methods GET HEAD; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; add_header X-Cache-Status $upstream_cache_status; fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; } }}缓存清除:Nginx 开源版本不支持主动缓存清除,可以通过以下方式实现:设置缓存过期时间:通过 proxy_cache_valid 控制使用第三方模块:如 ngxcachepurge手动删除缓存文件:根据缓存键删除对应文件缓存策略配置:# 根据请求方法缓存proxy_cache_methods GET HEAD;# 根据响应头缓存proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;# 缓存最小请求次数proxy_cache_min_uses 2;# 缓存锁定,防止缓存风暴proxy_cache_lock on;proxy_cache_lock_timeout 5s;# 缓存背景更新proxy_cache_background_update on;proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;动态缓存控制:# 根据条件决定是否缓存map $request_uri $skip_cache { default 0; ~*/admin/ 1; ~*/api/ 1;}# 根据响应头决定是否缓存map $upstream_http_cache_control $skip_cache { ~*no-cache 1; ~*private 1; default 0;}静态文件缓存:location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off;}缓存状态监控:add_header X-Cache-Status $upstream_cache_status;# 缓存状态值:# MISS - 未命中缓存# BYPASS - 绕过缓存# EXPIRED - 缓存过期# STALE - 使用过期缓存# UPDATING - 缓存更新中# HIT - 命中缓存缓存优化建议:合理设置缓存时间,平衡新鲜度和性能使用缓存键包含必要参数,避免缓存冲突对动态内容禁用缓存定期清理过期缓存监控缓存命中率,调整缓存策略使用缓存锁定防止缓存风暴对静态资源使用浏览器缓存完整配置示例:http { # 代理缓存 proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy_cache:100m max_size=10g inactive=60m use_temp_path=off; # FastCGI 缓存 fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=fastcgi_cache:100m max_size=10g inactive=60m; # 缓存跳过条件 map $request_uri $skip_cache { default 0; ~*/admin/ 1; ~*/api/ 1; ~*/user/ 1; } server { listen 80; server_name example.com; # 静态文件 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } # 动态内容代理 location / { proxy_cache proxy_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_bypass $skip_cache; proxy_no_cache $skip_cache; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; } # PHP 文件 location ~ \.php$ { fastcgi_cache fastcgi_cache; fastcgi_cache_valid 200 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; add_header X-Cache-Status $upstream_cache_status; fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; } }}
阅读 0·2月21日 16:57

Nginx 的 location 指令如何匹配?优先级是什么?

Nginx 的 location 指令如何匹配?优先级是什么?Nginx 的 location 指令用于匹配请求的 URI,并定义如何处理这些请求。理解 location 的匹配规则和优先级对于正确配置 Nginx 至关重要。Location 匹配规则:1. 精确匹配(=)使用 = 进行精确匹配,如果匹配成功,立即停止搜索并使用该 location。location = /exact { # 精确匹配 /exact}2. 前缀匹配(无修饰符)不使用任何修饰符,按前缀匹配,匹配成功后继续搜索更精确的匹配。location /prefix { # 匹配以 /prefix 开头的 URI}3. 正则匹配(~ 和 ~*)~:区分大小写的正则匹配~*:不区分大小写的正则匹配location ~ \.php$ { # 匹配以 .php 结尾的 URI(区分大小写)}location ~* \.(jpg|jpeg|png|gif)$ { # 匹配图片文件(不区分大小写)}4. 前缀匹配(^~)使用 ^~ 进行前缀匹配,如果匹配成功,立即停止搜索,不再检查正则表达式。location ^~ /static/ { # 匹配以 /static/ 开头的 URI,不再检查正则}匹配优先级(从高到低):精确匹配(=):优先级最高前缀匹配(^~):如果匹配成功,停止搜索正则匹配(~ 和 ~*):按配置顺序依次检查前缀匹配(无修饰符):优先级最低匹配示例:server { listen 80; server_name example.com; # 1. 精确匹配 location = / { return 200 "Exact match /"; } # 2. ^~ 前缀匹配 location ^~ /images/ { return 200 "Prefix match ^~ /images/"; } # 3. 正则匹配(区分大小写) location ~ \.php$ { return 200 "Regex match .php"; } # 4. 正则匹配(不区分大小写) location ~* \.(jpg|jpeg|png|gif)$ { return 200 "Regex match images"; } # 5. 普通前缀匹配 location / { return 200 "Prefix match /"; }}实际匹配结果:请求 / → 精确匹配 location = /请求 /images/logo.jpg → location ^~ /images/(停止搜索,不匹配正则)请求 /test.php → location ~ \.php$请求 /photo.JPG → location ~* \.(jpg|jpeg|png|gif)$(不区分大小写)请求 /other → location /嵌套 Location:location /api/ { # 外层 location proxy_pass http://backend; location /api/v1/ { # 内层 location,继承外层配置 proxy_pass http://backend_v1; }}使用建议:将精确匹配放在最前面将正则匹配放在中间将普通前缀匹配放在最后使用 ^~ 避免不必要的正则匹配合理使用正则匹配,避免过度使用影响性能性能考虑:精确匹配和 ^~ 匹配性能最好正则匹配需要编译和执行,性能相对较低避免使用复杂的正则表达式正则匹配按配置顺序执行,将常用匹配放在前面实际应用场景:# 静态文件缓存location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable";}# PHP 文件处理location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params;}# API 请求代理location /api/ { proxy_pass http://api_backend;}# 管理后台location ^~ /admin/ { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://admin_backend;}
阅读 0·2月21日 16:56

Nginx 如何配置虚拟主机?有哪些配置方式?

Nginx 如何配置虚拟主机?有哪些配置方式?Nginx 虚拟主机(Virtual Host)允许在同一台服务器上运行多个网站,通过不同的域名、端口或 IP 地址来区分不同的站点。基于域名的虚拟主机:server { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.html index.php; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; location / { try_files $uri $uri/ =404; }}server { listen 80; server_name test.com www.test.com; root /var/www/test.com; index index.html index.php; access_log /var/log/nginx/test.com.access.log; error_log /var/log/nginx/test.com.error.log; location / { try_files $uri $uri/ =404; }}基于端口的虚拟主机:server { listen 80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 8080; server_name example.com; root /var/www/example.com/admin; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 8443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; root /var/www/example.com/secure; index index.html; location / { try_files $uri $uri/ =404; }}基于 IP 地址的虚拟主机:server { listen 192.168.1.100:80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 192.168.1.101:80; server_name example.com; root /var/www/example.com/mirror; index index.html; location / { try_files $uri $uri/ =404; }}通配符域名:# 匹配所有子域名server { listen 80; server_name *.example.com; root /var/www/subdomains; index index.html; location / { # 使用子域名作为目录名 set $subdomain $host; if ($subdomain ~* ^(.*)\.example\.com$) { set $subdomain $1; } root /var/www/subdomains/$subdomain; }}# 匹配所有域名(默认虚拟主机)server { listen 80 default_server; server_name _; root /var/www/default; index index.html; location / { return 404; }}正则表达式域名:server { listen 80; server_name ~^(?<subdomain>.+)\.example\.com$; root /var/www/example.com/$subdomain; index index.html; location / { try_files $uri $uri/ =404; }}server { listen 80; server_name ~^(?<user>.+)\.users\.example\.com$; root /var/www/users/$user; index index.html; location / { try_files $uri $uri/ =404; }}HTTPS 虚拟主机: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_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}多域名共享配置:# 定义共享配置map $host $root_path { example.com /var/www/example.com; test.com /var/www/test.com; default /var/www/default;}server { listen 80; server_name example.com test.com; root $root_path; index index.html; location / { try_files $uri $uri/ =404; }}反向代理虚拟主机:upstream backend1 { server 192.168.1.100:8080; server 192.168.1.101:8080;}upstream backend2 { server 192.168.1.200:8080; server 192.168.1.201:8080;}server { listen 80; server_name api.example.com; location / { proxy_pass http://backend1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}server { listen 80; server_name admin.example.com; location / { proxy_pass http://backend2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}PHP 虚拟主机:server { listen 80; server_name example.com; root /var/www/example.com; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } 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; } location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }}静态站点虚拟主机:server { listen 80; server_name static.example.com; root /var/www/static; index index.html; # 启用 Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; # 静态资源缓存 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } location / { try_files $uri $uri/ =404; }}虚拟主机配置文件分离:# /etc/nginx/nginx.confhttp { include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;}# /etc/nginx/sites-available/example.comserver { listen 80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; }}# 创建符号链接启用站点# ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com虚拟主机最佳实践:配置文件分离:每个虚拟主机使用独立的配置文件命名规范:使用域名作为配置文件名日志分离:每个虚拟主机使用独立的日志文件默认主机:配置 default_server 处理未知请求SSL 配置:所有生产环境使用 HTTPS错误页面:为每个虚拟主机配置自定义错误页面安全头:添加安全相关的 HTTP 头性能优化:启用 Gzip 压缩和缓存完整虚拟主机配置示例:# /etc/nginx/sites-available/example.comserver { listen 80; server_name example.com www.example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri;}server { listen 443 ssl http2; server_name example.com www.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 HIGH:!aNULL:!MD5; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 根目录 root /var/www/example.com; index index.php index.html; # 日志 access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; # 安全头 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; # 静态资源 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$ { 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; } # 主路由 location / { try_files $uri $uri/ /index.php?$query_string; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; }}
阅读 0·2月21日 16:56

Nginx 常见问题有哪些?如何进行故障排查?

Nginx 常见问题有哪些?如何进行故障排查?Nginx 在运行过程中可能会遇到各种问题,掌握故障排查方法对于快速解决问题至关重要。常见问题及解决方案:1. 502 Bad Gateway原因:后端服务不可用或连接超时排查步骤:# 检查后端服务状态systemctl status php-fpmsystemctl status nginx# 检查后端服务端口netstat -tlnp | grep :9000# 检查 Nginx 错误日志tail -f /var/log/nginx/error.log# 检查后端服务日志tail -f /var/log/php-fpm/error.log解决方案:# 增加超时时间proxy_connect_timeout 60s;proxy_send_timeout 60s;proxy_read_timeout 60s;# 检查后端服务配置fastcgi_connect_timeout 60s;fastcgi_send_timeout 60s;fastcgi_read_timeout 60s;2. 504 Gateway Timeout原因:后端服务处理时间过长排查步骤:# 检查后端服务性能top -u nginxhtop# 检查数据库连接mysql -u root -p -e "SHOW PROCESSLIST;"# 检查慢查询日志tail -f /var/log/mysql/slow.log解决方案:# 增加超时时间proxy_read_timeout 300s;fastcgi_read_timeout 300s;# 优化后端服务性能# 优化数据库查询# 增加缓存3. 403 Forbidden原因:权限不足或访问控制限制排查步骤:# 检查文件权限ls -la /var/www/html# 检查 Nginx 用户ps aux | grep nginx# 检查 SELinux 状态getenforce# 检查防火墙规则iptables -L -n解决方案:# 修改文件权限chown -R nginx:nginx /var/www/htmlchmod -R 755 /var/www/html# 临时关闭 SELinuxsetenforce 0# 添加防火墙规则firewall-cmd --add-service=http --permanentfirewall-cmd --reload4. 404 Not Found原因:文件不存在或路径配置错误排查步骤:# 检查文件是否存在ls -la /var/www/html# 检查 Nginx 配置nginx -T | grep root# 检查符号链接readlink -f /var/www/html解决方案:# 检查 root 配置server { listen 80; server_name example.com; root /var/www/html; index index.html index.php; location / { try_files $uri $uri/ =404; }}5. 413 Request Entity Too Large原因:上传文件超过限制解决方案:# 增加 client_max_body_sizeclient_max_body_size 100m;# PHP 配置# /etc/php.iniupload_max_filesize = 100Mpost_max_size = 100M6. 连接数不足原因:worker_connections 设置过小排查步骤:# 检查当前连接数netstat -an | grep :80 | wc -l# 检查 Nginx 状态curl http://localhost/nginx_status# 检查系统限制ulimit -n解决方案:# 增加连接数events { worker_connections 10240;}# 增加文件描述符限制worker_rlimit_nofile 65535;诊断工具:1. 配置测试# 测试配置文件nginx -t# 显示配置nginx -T# 检查配置语法nginx -c /etc/nginx/nginx.conf -t2. 状态监控# 启用状态页面location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all;}3. 日志分析# 实时查看错误日志tail -f /var/log/nginx/error.log# 查看最近 100 行错误tail -n 100 /var/log/nginx/error.log# 搜索特定错误grep "502" /var/log/nginx/error.log# 统计错误数量awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn4. 性能分析# 使用 strace 追踪系统调用strace -p $(pidof nginx)# 使用 tcpdump 抓包tcpdump -i eth0 port 80 -w nginx.pcap# 使用 netstat 查看连接netstat -an | grep :80 | awk '{print $6}' | sort | uniq -c性能问题排查:1. CPU 使用率高# 检查 CPU 使用top -p $(pidof nginx)# 检查 worker 进程数ps aux | grep nginx | wc -l# 检查 CPU 亲和性taskset -cp $(pidof nginx)解决方案:# 调整 worker_processesworker_processes auto;# 绑定 CPU 核心worker_cpu_affinity auto;# 启用高效文件传输sendfile on;tcp_nopush on;2. 内存使用过高# 检查内存使用free -m# 检查进程内存ps aux | grep nginx | awk '{print $6}' | awk '{sum+=$1} END {print sum}'# 检查内存泄漏valgrind --leak-check=full nginx解决方案:# 减少缓冲区大小client_body_buffer_size 128k;client_header_buffer_size 1k;# 优化连接数worker_connections 4096;# 启用文件缓存open_file_cache max=100000 inactive=20s;3. 响应慢# 检查响应时间curl -w "@curl-format.txt" -o /dev/null -s http://example.com# 检查网络延迟ping example.com# 检查 DNS 解析nslookup example.com解决方案:# 启用 Gzip 压缩gzip on;gzip_min_length 1024;# 启用缓存proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m;# 优化 TCP 参数tcp_nodelay on;tcp_nopush on;安全问题排查:1. DDoS 攻击# 检查异常连接netstat -an | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn# 检查请求频率awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20解决方案:# 启用限流limit_req_zone $binary_remote_addr zone=limit:10m rate=10r/s;limit_req zone=limit burst=20 nodelay;# 限制连接数limit_conn_zone $binary_remote_addr zone=conn:10m;limit_conn conn 10;2. 恶意访问# 检查可疑 User-Agentgrep "bot" /var/log/nginx/access.log# 检查 SQL 注入尝试grep "union.*select" /var/log/nginx/access.log解决方案:# 阻止恶意 User-Agentif ($http_user_agent ~* (bot|crawl|spider)) { return 403;}# 防止 SQL 注入if ($args ~* "union.*select.*\(") { return 403;}监控和告警:1. 系统监控# 使用 Prometheus + Grafana# 使用 Zabbix# 使用 Nagios2. 日志监控# 使用 ELK Stack# 使用 Graylog# 使用 Fluentd3. 自动告警# 使用 Alertmanager# 使用 PagerDuty# 使用 Slack 集成最佳实践:定期备份配置:备份 Nginx 配置文件监控日志:实时监控错误日志性能测试:定期进行压力测试文档记录:记录常见问题和解决方案自动化部署:使用配置管理工具版本控制:使用 Git 管理配置文件定期更新:保持 Nginx 版本最新安全审计:定期进行安全检查故障排查流程:1. 确认问题现象 ↓2. 检查 Nginx 状态 ↓3. 查看错误日志 ↓4. 检查配置文件 ↓5. 检查后端服务 ↓6. 检查系统资源 ↓7. 应用解决方案 ↓8. 验证修复效果 ↓9. 记录问题和解决方案
阅读 0·2月21日 16:50

Nginx 常见的部署架构有哪些?如何选择合适的架构?

Nginx 常见的部署架构有哪些?如何选择合适的架构?Nginx 可以根据不同的业务需求和规模采用多种部署架构,从单机部署到分布式集群都有相应的解决方案。单机部署架构:客户端 → Nginx → 应用服务器 → 数据库适用场景:小型网站或应用开发测试环境低流量业务配置示例:server { listen 80; server_name example.com; root /var/www/html; index index.php index.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; } location / { try_files $uri $uri/ =404; }}反向代理架构:客户端 → Nginx (反向代理) → 后端服务器集群适用场景:多个应用服务器需要统一入口需要负载均衡需要隐藏后端服务器配置示例:upstream backend { server 192.168.1.100:8080 weight=3; server 192.168.1.101:8080 weight=2; server 192.168.1.102:8080 weight=1; keepalive 32;}server { listen 80; server_name example.com; 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; }}负载均衡架构:客户端 → Nginx (负载均衡器) → 后端服务器池适用场景:高并发访问需要水平扩展需要高可用性负载均衡策略:# 轮询(默认)upstream backend { server 192.168.1.100:8080; server 192.168.1.101:8080;}# 最少连接upstream backend { least_conn; server 192.168.1.100:8080; server 192.168.1.101:8080;}# IP 哈希upstream backend { ip_hash; server 192.168.1.100:8080; server 192.168.1.101:8080;}# 加权轮询upstream backend { server 192.168.1.100:8080 weight=3; server 192.168.1.101:8080 weight=2; server 192.168.1.102:8080 weight=1;}多层代理架构:客户端 → 边缘 Nginx → 中间 Nginx → 应用服务器适用场景:大规模分布式系统需要多层缓存需要安全隔离配置示例:# 边缘 Nginxupstream middle_layer { server 192.168.1.200:80; server 192.168.1.201:80;}server { listen 80; server_name example.com; location / { proxy_pass http://middle_layer; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }}# 中间层 Nginxupstream backend { server 192.168.1.100:8080; server 192.168.1.101:8080;}server { listen 80; server_name middle.example.com; location / { proxy_pass http://backend; proxy_set_header Host $host; }}CDN 集成架构:客户端 → CDN → 源站 Nginx → 后端服务器适用场景:全球用户访问需要加速静态资源需要减轻源站压力配置示例:server { listen 80; server_name example.com; # 静态资源重定向到 CDN location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { return 301 https://cdn.example.com$request_uri; } # 动态内容 location / { proxy_pass http://backend; proxy_set_header Host $host; }}高可用架构(Keepalived + Nginx):客户端 → VIP (虚拟IP) ↓ Nginx 主节点 ← Keepalived ↓ Nginx 备节点 ← Keepalived ↓ 后端服务器适用场景:需要高可用性不能接受单点故障关键业务系统配置示例:# 主节点 Nginx 配置upstream backend { server 192.168.1.100:8080; server 192.168.1.101:8080;}server { listen 80; server_name example.com; location / { proxy_pass http://backend; proxy_set_header Host $host; }}# Keepalived 配置vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1234 } virtual_ipaddress { 192.168.1.50 }}微服务架构:客户端 → Nginx (API 网关) → 微服务集群适用场景:微服务架构需要统一 API 入口需要服务发现配置示例:# 用户服务upstream user_service { server 192.168.1.100:8080; server 192.168.1.101:8080;}# 订单服务upstream order_service { server 192.168.1.200:8080; server 192.168.1.201:8080;}# 支付服务upstream payment_service { server 192.168.1.300:8080; server 192.168.1.301:8080;}server { listen 80; server_name api.example.com; # 路由到用户服务 location /api/users/ { proxy_pass http://user_service; proxy_set_header Host $host; } # 路由到订单服务 location /api/orders/ { proxy_pass http://order_service; proxy_set_header Host $host; } # 路由到支付服务 location /api/payments/ { proxy_pass http://payment_service; proxy_set_header Host $host; }}缓存架构:客户端 → Nginx (缓存层) → 后端服务器适用场景:读多写少的应用需要减轻后端压力需要提升响应速度配置示例:# 定义缓存路径proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy_cache:10m max_size=1g inactive=60m;upstream backend { server 192.168.1.100:8080; server 192.168.1.101:8080;}server { listen 80; server_name example.com; location / { # 启用缓存 proxy_cache proxy_cache; proxy_cache_valid 200 10m; proxy_cache_valid 404 1m; proxy_cache_key "$scheme$request_method$host$request_uri"; # 缓存跳过条件 proxy_cache_bypass $http_cache_control; proxy_no_cache $http_cache_control; proxy_pass http://backend; proxy_set_header Host $host; # 添加缓存状态头 add_header X-Cache-Status $upstream_cache_status; }}混合架构:客户端 → Nginx (静态资源) → CDN ↓ Nginx (动态内容) → 应用服务器适用场景:复杂业务系统需要分离静态和动态内容需要多种优化策略配置示例:# 静态资源服务器server { listen 80; server_name static.example.com; root /var/www/static; location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; }}# 动态内容服务器upstream backend { server 192.168.1.100:8080; server 192.168.1.101:8080;}server { listen 80; server_name example.com; location / { proxy_pass http://backend; proxy_set_header Host $host; }}架构选择指南:| 业务需求 | 推荐架构 | 说明 ||---------|-----------|------|| 小型网站 | 单机部署 | 简单易维护 || 中型应用 | 反向代理 | 统一入口,负载均衡 || 高并发 | 负载均衡架构 | 水平扩展,高可用 || 全球业务 | CDN 集成架构 | 加速访问,减轻源站压力 || 关键业务 | 高可用架构 | 避免单点故障 || 微服务 | 微服务架构 | 统一 API 网关 || 读多写少 | 缓存架构 | 提升性能,减轻后端压力 |部署架构最佳实践:渐进式扩展:从简单架构开始,根据需求逐步扩展监控告警:实时监控架构状态,及时发现问题容灾备份:配置备份和容灾方案安全防护:在架构各层添加安全措施性能优化:根据业务特点选择合适的优化策略文档记录:详细记录架构设计和配置定期演练:定期进行故障演练,验证架构可靠性成本控制:在满足需求的前提下控制成本
阅读 0·2月21日 16:50

什么是 Nginx?它的主要特点是什么?

什么是 Nginx?它的主要特点是什么?Nginx 是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3 代理服务器。它由 Igor Sysoev 开发,最初发布于2004年,旨在解决 C10k 问题,即同时处理大量客户端连接的需求。Nginx 的主要特点:高性能:采用事件驱动架构,能够处理数以万计的并发连接,内存占用低稳定性强:在高并发环境下表现稳定,能够长时间运行而不崩溃反向代理:可以作为反向代理服务器,将请求转发到后端服务器负载均衡:支持多种负载均衡算法,如轮询、最少连接、IP 哈希等静态文件服务:高效地提供静态文件服务,如 HTML、CSS、JavaScript、图片等缓存功能:支持 FastCGI、uWSGI、SCGI、memcached 等缓存SSL/TLS 支持:支持 HTTPS 协议,可以配置 SSL 证书模块化设计:通过模块扩展功能,支持第三方模块热部署:支持在不中断服务的情况下重新加载配置跨平台:支持 Linux、Windows、macOS 等多种操作系统与 Apache 的区别:Nginx 采用事件驱动、非阻塞 I/O 模型,Apache 采用进程/线程模型Nginx 在高并发场景下性能更好,资源消耗更低Apache 模块更丰富,动态处理能力更强Nginx 配置相对简单,学习曲线较平缓适用场景:高并发 Web 服务器反向代理服务器负载均衡器静态资源服务器API 网关WebSocket 代理
阅读 0·2月21日 16:45

Nginx 的事件驱动模型是什么?如何实现高并发?

Nginx 的事件驱动模型是什么?如何实现高并发?Nginx 采用事件驱动、非阻塞 I/O 模型,这是其能够处理高并发连接的核心原因。理解 Nginx 的事件驱动模型对于优化性能和解决高并发问题至关重要。事件驱动模型原理:Nginx 使用事件驱动架构,通过事件通知机制来处理 I/O 操作,而不是传统的多进程或多线程模型。核心概念:事件循环(Event Loop):主循环监听和处理各种事件事件处理器:处理特定类型事件的函数非阻塞 I/O:I/O 操作不会阻塞进程异步处理:通过回调函数处理 I/O 完成事件工作流程:1. Master 进程启动,监听端口2. Fork 多个 Worker 进程3. 每个 Worker 进程独立运行事件循环4. 事件循环监听连接、读写事件5. 事件触发时调用对应的处理器6. 处理完成后继续监听Nginx 进程模型:# nginx.conf 配置worker_processes auto; # 自动设置 worker 进程数,通常等于 CPU 核心数worker_rlimit_nofile 65535; # 每个 worker 打开的文件描述符限制events { worker_connections 10240; # 每个 worker 的最大连接数 use epoll; # 使用 epoll 事件模型(Linux) multi_accept on; # 允许同时接受多个连接}理论并发连接数:最大并发连接数 = worker_processes × worker_connections例如:4 个 worker,每个 10240 连接 = 40960 并发连接事件模型类型:Linux - epoll:events { use epoll;}高效处理大量连接O(1) 时间复杂度支持边缘触发和水平触发BSD/macOS - kqueue:events { use kqueue;}Windows - select/poll:events { use select;}高并发优化配置:# 全局配置user nginx;worker_processes auto;worker_rlimit_nofile 100000;events { worker_connections 65535; use epoll; multi_accept on; accept_mutex off; # 关闭互斥锁,提高并发性能}http { # 连接优化 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;}性能调优参数:worker_processes:设置为 auto 或 CPU 核心数worker_connections:根据内存和业务需求调整workerrlimitnofile:设置足够大的文件描述符限制multi_accept:允许同时接受多个新连接accept_mutex:高并发时关闭,减少锁竞争系统级优化:# /etc/sysctl.conf# 增加系统文件描述符限制fs.file-max = 1000000# 优化 TCP 参数net.ipv4.tcp_max_tw_buckets = 6000net.ipv4.tcp_sack = 1net.ipv4.tcp_window_scaling = 1net.ipv4.tcp_rmem = 4096 87380 4194304net.ipv4.tcp_wmem = 4096 65536 4194304net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.core.netdev_max_backlog = 262144net.ipv4.tcp_max_syn_backlog = 262144net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_tw_reuse = 1与 Apache 的对比:| 特性 | Nginx | Apache ||------|-------|--------|| 模型 | 事件驱动 | 进程/线程 || 内存占用 | 低 | 高 || 并发能力 | 高 | 中等 || CPU 使用 | 低 | 高 || 动态处理 | 较弱 | 强 |监控和诊断:# 启用状态监控location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all;}状态信息包括:Active connections:当前活动连接数accepts:已接受的连接总数handled:已处理的连接总数requests:已处理的请求总数Reading:正在读取请求头的连接数Writing:正在发送响应的连接数Waiting:空闲连接数实际应用场景:高并发 Web 服务器:处理数万并发连接反向代理:作为入口网关负载均衡:分发请求到后端静态资源服务:高效提供静态文件性能测试:使用 wrk 或 ab 进行压力测试:# 使用 wrk 测试wrk -t12 -c4000 -d30s http://example.com/# 使用 ab 测试ab -n 10000 -c 1000 http://example.com/常见问题解决:连接数不足:增加 worker_connections 和系统文件描述符限制CPU 使用率高:检查 worker_processes 设置,避免过多内存不足:优化缓冲区大小,减少 worker_connections性能瓶颈:使用 epoll,开启 multiaccept,关闭 acceptmutex
阅读 0·2月21日 16:45

Nginx 的负载均衡有哪些策略?如何配置?

Nginx 的负载均衡有哪些策略?如何配置?Nginx 提供了多种负载均衡策略,可以根据不同的业务需求选择合适的算法。负载均衡通过 upstream 模块实现,可以将请求分发到多个后端服务器。主要负载均衡策略:1. 轮询(Round Robin,默认)按顺序依次将请求分配给每个服务器,适用于服务器性能相近的场景。upstream backend { server 192.168.1.100:8080; server 192.168.1.101:8080; server 192.168.1.102:8080;}2. 最少连接(Least Connections)将请求分配给当前活动连接数最少的服务器,适用于请求处理时间差异较大的场景。upstream backend { least_conn; server 192.168.1.100:8080; server 192.168.1.101:8080; server 192.168.1.102:8080;}3. IP 哈希(IP Hash)根据客户端 IP 地址进行哈希计算,确保同一 IP 的请求总是分配到同一台服务器,适用于需要会话保持的场景。upstream backend { ip_hash; server 192.168.1.100:8080; server 192.168.1.101:8080; server 192.168.1.102:8080;}4. 加权轮询(Weighted Round Robin)为每台服务器设置权重,权重高的服务器接收更多请求,适用于服务器性能不均衡的场景。upstream backend { server 192.168.1.100:8080 weight=3; server 192.168.1.101:8080 weight=2; server 192.168.1.102:8080 weight=1;}5. 哈希(Hash)根据指定的 key 进行哈希计算,可以是变量如 $requesturi、$cookiename 等。upstream backend { hash $request_uri consistent; server 192.168.1.100:8080; server 192.168.1.101:8080;}服务器状态参数:upstream backend { server 192.168.1.100:8080 weight=3 max_fails=3 fail_timeout=30s; server 192.168.1.101:8080 weight=2 max_fails=3 fail_timeout=30s; server 192.168.1.102:8080 down; server 192.168.1.103:8080 backup;}weight:服务器权重,默认为 1max_fails:允许的最大失败次数,超过则标记为不可用fail_timeout:失败超时时间,在标记不可用后的等待时间down:标记服务器为永久不可用backup:标记为备用服务器,只在主服务器都不可用时使用max_conns:限制最大并发连接数完整配置示例:http { upstream backend { least_conn; server 192.168.1.100:8080 weight=3 max_fails=3 fail_timeout=30s; server 192.168.1.101:8080 weight=2 max_fails=3 fail_timeout=30s; server 192.168.1.102:8080 weight=1 max_fails=3 fail_timeout=30s; server 192.168.1.103:8080 backup; keepalive 32; } server { listen 80; server_name example.com; 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; } }}健康检查:Nginx 开源版本不提供主动健康检查,但可以通过被动健康检查(maxfails/failtimeout)实现。商业版 Nginx Plus 提供主动健康检查功能。选择策略建议:服务器性能相近:使用轮询请求处理时间差异大:使用最少连接需要会话保持:使用 IP 哈希服务器性能不均衡:使用加权轮询需要基于特定 key 分发:使用 hash
阅读 0·2月21日 16:45

如何动态修改 nginx 的配置信息?

动态配置 Nginx 的方法确实,动态配置 Nginx 是在不重启服务的情况下更改配置的实用能力。这对于需要高可用性的生产环境尤其重要。以下是几种可以实现动态配置Nginx的方法:1. 使用 nginx -s reload这是最常见的动态修改Nginx配置的方法。修改完nginx的配置文件后,可以使用 nginx -s reload 命令来重新加载配置文件,这样做可以不中断服务。这个命令实际上会启动新的worker进程,并逐渐停止旧的worker进程。例如:sudo nginx -s reload2. 使用 Consul 和 Consul TemplateConsul 是一个服务网络解决方案,可以用来动态地处理服务发现和配置。搭配使用 Consul Template 可以动态生成Nginx配置文件。Consul Template 监控Consul的状态变化,一旦检测到变化,就会重新渲染配置模板并重新加载Nginx。这种方法适用于基于服务发现的动态配置场景。3. 使用 OpenRestyOpenResty 是一个基于Nginx与Lua的动态web平台,它允许通过编写Lua脚本来动态地更改配置逻辑。例如,可以在access阶段根据请求的不同动态改变代理服务器或者其他配置。这种方法提供了极高的灵活性。4. 使用 Docker 容器在Docker容器中运行Nginx时,可以通过更新Docker容器的配置来实现Nginx的动态配置。这通常涉及到使用环境变量或挂载配置卷来修改配置。容器化管理工具(如Kubernetes)可以在不停机的情况下滚动更新Nginx配置。5. 动态模块Nginx也支持动态模块,这些模块可以在不重新编译Nginx的情况下加载或卸载。这使得用户可以根据需要添加或删除功能,虽然这不直接修改Nginx的配置文件,但它提供了一种方式来扩展Nginx的功能而不需要重启服务。结论动态配置Nginx主要目的是减少因配置更改而导致的服务中断。上述方法各有优势,适用于不同的场景和需求。在选择具体的实现方式时,应评估实际的业务需求、资源和技术栈。
阅读 60·2024年7月15日 23:58