Java面试题47:一文深入了解Nginx

张开发
2026/5/17 9:31:28 15 分钟阅读
Java面试题47:一文深入了解Nginx
Nginx 是一款高性能的 HTTP 和反向代理服务器也是一个 IMAP/POP3/SMTP 代理服务器以高并发、低内存占用、稳定性强著称。一、基础概念与核心原理1. 什么是 Nginx它有哪些特点定义Nginx 是由 Igor Sysoev 开发的开源轻量级 Web 服务器、反向代理服务器和电子邮件代理服务器采用事件驱动的异步非阻塞架构。核心特点高并发单台服务器可支持数万甚至数十万并发连接默认配置下约 1-2 万调优后可达 10 万 低内存1 万并发连接仅占用约 2.5MB 内存高可用支持热部署7×24 小时不间断运行模块化丰富的第三方模块生态反向代理与负载均衡内置多种负载均衡策略静态资源处理高效处理静态文件比 Apache 快 10 倍以上2. Nginx 和 Apache 的区别特性NginxApache架构异步非阻塞事件驱动同步阻塞多进程 / 多线程并发高并发支持数万连接低并发默认约 1000 连接内存占用极低较高静态资源极强一般动态请求需转发给后端处理原生支持 PHP 等模块核心模块 第三方模块编译时加载模块丰富支持动态加载配置简洁灵活复杂繁琐适用场景静态服务、反向代理、负载均衡动态服务、传统 Web 应用3. Nginx 的工作原理核心中的核心Nginx 采用多进程 异步非阻塞事件模型epoll/kqueue。进程模型Master 进程管理进程负责读取配置、启动 / 停止 Worker 进程、监控 Worker 状态、热部署Worker 进程工作进程实际处理网络请求数量通常设置为 CPU 核心数worker_processes autoCache 进程可选包括 Cache Manager 和 Cache Loader负责缓存管理请求处理流程客户端发送请求到 Nginx 的 80/443 端口Master 进程接收请求将其分配给空闲的 Worker 进程Worker 进程通过 epoll 模型监听事件非阻塞地处理请求如果是静态资源直接返回给客户端如果是动态请求通过反向代理转发给后端服务器如 Tomcat、PHP-FPM后端服务器处理完成后将结果返回给 NginxNginx 将结果返回给客户端4. 什么是异步非阻塞Nginx 如何实现同步阻塞进程发起请求后必须等待请求完成才能继续执行期间 CPU 空闲异步非阻塞进程发起请求后立即返回继续执行其他任务当请求完成时通过事件通知进程处理结果Nginx 使用epollLinux或kqueueFreeBSD实现异步非阻塞epoll 是 Linux 内核提供的 I/O 多路复用技术它将所有需要监听的文件描述符注册到 epoll 实例中当某个文件描述符有事件发生时epoll 会通知对应的 Worker 进程Worker 进程只处理有事件的连接避免了轮询所有连接的开销5. Nginx 如何处理高并发多进程模型充分利用多核 CPU每个 Worker 进程独立运行互不影响异步非阻塞 I/O一个 Worker 进程可以同时处理数千个连接事件驱动只处理有事件的连接避免了空闲连接的资源浪费内存池预分配内存减少内存碎片和分配开销连接池复用 TCP 连接减少三次握手和四次挥手的开销静态资源缓存将静态资源缓存在内存中直接返回给客户端二、常用配置详解1. Nginx 配置文件结构Nginx 配置文件默认位于/etc/nginx/nginx.conf由指令和指令块组成指令以分号结尾指令块用大括号包裹。# 全局块配置影响Nginx全局的指令 user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # events块配置影响Nginx服务器与用户网络连接的指令 events { worker_connections 1024; # 每个Worker进程的最大连接数 use epoll; # 使用epoll事件模型 multi_accept on; # 允许同时接受多个新连接 } # http块配置HTTP服务器的主要参数 http { include /etc/nginx/mime.types; default_type application/octet-stream; # 日志格式 log_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for; access_log /var/log/nginx/access.log main; sendfile on; # 开启高效文件传输模式 tcp_nopush on; # 防止网络阻塞 tcp_nodelay on; # 防止网络阻塞 keepalive_timeout 65; # 长连接超时时间 gzip on; # 开启gzip压缩 # server块配置虚拟主机 server { listen 80; # 监听端口 server_name example.com; # 域名 root /usr/share/nginx/html; # 网站根目录 index index.html index.htm; # 默认首页 # location块配置请求路由 location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend; # 反向代理到后端服务器 } } # upstream块配置负载均衡服务器组 upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; } }2. 常用配置指令详解全局块user nginx指定 Nginx 运行的用户和组worker_processes autoWorker 进程数建议设置为 CPU 核心数error_log /var/log/nginx/error.log warn错误日志路径和级别pid /run/nginx.pidPID 文件路径events 块worker_connections 1024每个 Worker 进程的最大连接数总连接数 worker_processes×worker_connectionsuse epoll指定使用 epoll 事件模型Linux 默认multi_accept on允许 Worker 进程同时接受多个新连接http 块sendfile on开启 sendfile 系统调用直接在内核中传输文件避免用户态和内核态之间的拷贝tcp_nopush on当 sendfile 开启时将多个小数据包合并成一个大数据包发送提高网络效率tcp_nodelay on禁用 Nagle 算法允许小数据包立即发送适用于实时性要求高的场景keepalive_timeout 65长连接超时时间单位秒gzip on开启 gzip 压缩减少传输带宽gzip_types text/plain text/css application/json application/javascript指定需要压缩的文件类型server 块listen 80监听端口server_name example.com www.example.com指定域名支持多个域名和通配符root /usr/share/nginx/html网站根目录index index.html index.htm默认首页error_page 404 /404.html自定义 404 页面error_page 500 502 503 504 /50x.html自定义 5xx 错误页面location 块location 用于匹配请求 URI语法location [|~|~*|^~] /uri/ { ... }修饰符含义匹配优先级精确匹配最高^~前缀匹配匹配成功后不再进行正则匹配次高~正则匹配区分大小写中~*正则匹配不区分大小写中无修饰符前缀匹配最低location / { # 精确匹配根目录 } location ^~ /static/ { # 匹配所有以/static/开头的请求不再进行正则匹配 root /usr/share/nginx; } location ~* \.(jpg|jpeg|png|gif|css|js)$ { # 匹配所有图片和静态文件不区分大小写 expires 30d; # 设置缓存时间为30天 } location / { # 匹配所有其他请求 }3. 反向代理配置 反向代理是 Nginx 最常用的功能之一用于将客户端请求转发给后端服务器。location /api/ { proxy_pass http://127.0.0.1:8080; # 后端服务器地址 proxy_set_header Host $host; # 传递Host头 proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链IP proxy_connect_timeout 60s; # 连接后端超时时间 proxy_read_timeout 60s; # 读取后端响应超时时间 proxy_send_timeout 60s; # 发送请求到后端超时时间 }4. 负载均衡配置Nginx 内置多种负载均衡策略通过 upstream 块配置。轮询默认请求按顺序依次分配给后端服务器。upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; }加权轮询权重越高的服务器分配到的请求越多。upstream backend { server 192.168.1.10:8080 weight3; server 192.168.1.11:8080 weight1; }IP 哈希根据客户端 IP 的哈希值分配服务器保证同一个客户端的请求始终分配到同一个服务器解决 session 问题。upstream backend { ip_hash; server 192.168.1.10:8080; server 192.168.1.11:8080; }最少连接请求分配给当前连接数最少的服务器。upstream backend { least_conn; server 192.168.1.10:8080; server 192.168.1.11:8080; }健康检查Nginx 内置被动健康检查当后端服务器出现错误时自动将其从负载均衡池中移除。upstream backend { server 192.168.1.10:8080 max_fails3 fail_timeout30s; server 192.168.1.11:8080 max_fails3 fail_timeout30s; }max_fails3允许失败的次数fail_timeout30s失败后服务器被暂停服务的时间5. HTTPS 配置HTTPS 基于 SSL/TLS 协议用于加密 HTTP 通信保证数据传输安全。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; # 私钥文件 ssl_protocols TLSv1.2 TLSv1.3; # 支持的SSL/TLS版本 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 加密套件 ssl_prefer_server_ciphers on; # 优先使用服务器端的加密套件 ssl_session_cache shared:SSL:10m; # SSL会话缓存 ssl_session_timeout 10m; # SSL会话超时时间 location / { root /usr/share/nginx/html; index index.html; } } # HTTP重定向到HTTPS server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; }三、应用场景静态资源服务器高效处理 HTML、CSS、JS、图片等静态文件反向代理服务器隐藏后端服务器提高安全性和性能负载均衡器将请求分发到多个后端服务器提高系统可用性和并发能力API 网关统一入口实现路由、限流、鉴权、日志等功能缓存服务器缓存静态资源和动态页面减少后端服务器压力SSL 终端统一处理 HTTPS 加密和解密减轻后端服务器负担动静分离静态资源由 Nginx 处理动态请求转发给后端服务器四、安全防护1. 隐藏 Nginx 版本号http { server_tokens off; # 隐藏响应头中的Server版本号 }2. 禁止非法请求方法location / { if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; } }3. 防止 SQL 注入location / { if ($args ~* union.*select.*\() { return 403; } if ($args ~* concat.*\() { return 403; } }4. 防止目录遍历location / { if ($uri ~* \.\.) { return 403; } }5. 限制 IP 访问location /admin/ { allow 192.168.1.0/24; deny all; }6. 配置 WAFWeb 应用防火墙使用第三方模块如 ModSecurity实现更强大的安全防护。7. 配置 HTTPS强制使用 HTTPS禁用不安全的 SSL/TLS 版本和加密套件。五、性能调优1. 进程调优worker_processes auto; # 设置为CPU核心数 worker_cpu_affinity auto; # 将Worker进程绑定到不同的CPU核心 worker_rlimit_nofile 65535; # 每个Worker进程的最大文件描述符数2. 连接调优events { use epoll; worker_connections 65535; # 每个Worker进程的最大连接数 multi_accept on; } http { keepalive_timeout 65; keepalive_requests 1000; # 一个长连接最多处理的请求数 tcp_nopush on; tcp_nodelay on; }3. 静态资源调优http { sendfile on; sendfile_max_chunk 1m; # 每次sendfile传输的最大数据量 location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ { expires 30d; # 设置缓存时间 add_header Cache-Control public, max-age2592000; add_header ETag ; # 禁用ETag } }4. 压缩调优http { gzip on; gzip_vary on; gzip_comp_level 6; # 压缩级别1-9越高压缩率越高CPU消耗越大 gzip_min_length 1k; # 只压缩大于1k的文件 gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript; }5. 缓存调优http { proxy_cache_path /var/cache/nginx levels1:2 keys_zonecache:10m inactive60m max_size1g; location /api/ { proxy_pass http://backend; proxy_cache cache; proxy_cache_valid 200 304 1h; # 缓存200和304响应1小时 proxy_cache_key $host$uri$is_args$args; add_header X-Cache $upstream_cache_status; # 显示缓存状态 } }6. 系统内核调优修改/etc/sysctl.conf文件net.core.somaxconn 65535 # 最大待处理连接数 net.ipv4.tcp_syncookies 1 # 开启SYN Cookies防止SYN洪水攻击 net.ipv4.tcp_fin_timeout 30 # TCP连接关闭后的超时时间 net.ipv4.tcp_tw_reuse 1 # 允许将TIME-WAIT状态的连接重新用于新的TCP连接 net.ipv4.tcp_tw_recycle 1 # 开启TIME-WAIT状态连接的快速回收 net.ipv4.tcp_max_tw_buckets 5000 # 系统同时保持TIME-WAIT状态的最大数量 net.ipv4.tcp_max_syn_backlog 65535 # SYN队列的最大长度 net.core.netdev_max_backlog 5000 # 网络设备接收数据包的速率比内核处理快时允许送到队列的数据包的最大数目执行sysctl -p使配置生效。六、高级特性1. 热部署Nginx 支持热部署无需停止服务即可更新配置和升级版本。重新加载配置nginx -s reload优雅停止服务nginx -s quit强制停止服务nginx -s stopnginx -s reloadmaster 重新加载配置启动新 worker新请求交给新 worker旧 worker 处理完已有连接后退出服务不中断。2. 限流Nginx 支持基于连接数和请求数的限流。基于请求数的限流http { limit_req_zone $binary_remote_addr zonereq_limit:10m rate10r/s; server { location / { limit_req zonereq_limit burst5 nodelay; } } }rate10r/s每秒允许 10 个请求burst5允许突发 5 个请求nodelay突发请求立即处理不延迟基于连接数的限流http { limit_conn_zone $binary_remote_addr zoneconn_limit:10m; server { location / { limit_conn conn_limit 10; # 每个IP最多10个连接 } } }3. 灰度发布通过 Nginx 实现灰度发布将部分用户流量引导到新版本。upstream old { server 192.168.1.10:8080; } upstream new { server 192.168.1.11:8080; } split_clients ${remote_addr}AAA $variant { 10% new; * old; } server { listen 80; server_name example.com; location / { proxy_pass http://$variant; } }4. 防盗链防止其他网站盗用本站资源。location ~* \.(jpg|jpeg|png|gif)$ { valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; } }七、高频面试题汇总Nginx 为什么这么快Nginx 和 Apache 的区别Nginx 的工作原理Nginx 如何处理高并发什么是反向代理和正向代理有什么区别Nginx 有哪些负载均衡策略location 的匹配规则和优先级如何配置 HTTPSNginx 如何实现动静分离Nginx 如何实现限流Nginx 如何实现灰度发布Nginx 如何隐藏版本号Nginx 热部署的原理Nginx 常见的状态码有哪些分别表示什么如何排查 Nginx 502 错误八、分层网关架构绝大多数企业架构是Nginx SCG 一起用各司其职互联网 → 【Nginx边缘网关】 → 【SCG业务网关】 → 微服务集群Nginx 做第一层HTTPS 终结证书、TLS 优化公网流量清洗防刷、黑名单、全局限流静态资源直接返回动静分离四层负载均衡多机房 / 多集群分发安全屏障隐藏内网拓扑SCG 做第二层微服务智能路由自动发现、动态配置业务级鉴权JWT、权限校验熔断降级、接口限流、重试请求 / 响应修改、日志、监控灰度发布、A/B 测试Nginx定位边缘流量网关 / 通用 Web 服务器 / 反向代理语言C 语言开发架构多进程 异步非阻塞 epoll 事件驱动擅长高并发、低延迟、静态资源、SSL 卸载、四层 / 七层负载均衡角色公网入口、流量门卫、基础设施Spring Cloud Gateway定位微服务 API 网关 / 业务网关语言Java基于 Spring WebFlux Netty Reactor架构响应式异步非阻塞Netty 线程模型擅长动态路由、服务发现、熔断限流、认证鉴权、业务过滤、微服务治理角色内部流量调度、业务逻辑网关一句话总结Nginx 管流量与性能SCG 管业务与微服务生态。1. Nginx 和 Spring Cloud Gateway 核心区别定位不同Nginx 是流量 / 基础设施网关SCG 是业务 / 微服务网关。技术栈Nginx C 语言性能极致SCG Java生态强、易扩展。场景Nginx 管公网入口、静态、SSL、高并发SCG 管微服务路由、业务逻辑、治理。2. 为什么微服务还要用 Nginx性能扛压Nginx 抗公网高并发保护内部 SCG。SSL 卸载减轻 SCG 的加密计算压力。静态分离静态不走 Java 网关节省资源。安全隔离隐藏内网服务地址。3. 什么时候可以只用 SCG 不用 Nginx内网环境、无 HTTPS、中小流量云原生用云厂商 LBSLB/ALB替代 Nginx测试 / 开发环境简化架构

更多文章