1. Nginx 和 Apache 区别?为啥 Nginx 性能更好?
口述: 最核心差别是进程模型和 IO 模型。Apache 是多进程多线程,一个连接对应一个线程,并发高了上下文切换开销很大;Nginx 是 Master-Worker 模型,少量 Worker 进程配合异步非阻塞 IO、epoll 多路复用,一个 Worker 可以维护上万条连接。 而且 Nginx 支持 sendfile 零拷贝,静态文件直接内核转发,内存 CPU 占用更低,更适合高并发、静态资源、反向代理负载均衡场景。Apache 优势是模块丰富、动态内容兼容性好,现在高并发场景基本优先 Nginx。
2. Master-Worker 架构
口述: Nginx 分 Master 主进程和 Worker 工作进程,还有可选的缓存管理进程。 Master 只负责读取解析配置、管理 Worker、接收信号做平滑重启,不处理业务请求; Worker 进程才真正跑事件循环、处理请求,一般设置成和 CPU 核心数一致,多个 Worker 相互独立,减少锁竞争。 平滑重启就是 Master 拉起新 Worker 加载新配置,老 Worker 把存量请求处理完自动退出,业务不断。
3. Nginx 怎么实现高并发?事件驱动 + epoll
口述: 核心是 Reactor 事件驱动 + Linux 的 epoll IO 多路复用。 传统 select/poll 要遍历所有连接,效率低;epoll 在内核维护就绪事件列表,只返回有读写事件的连接,不用轮询所有 fd。 Nginx 的 Worker 是异步非阻塞,没有事件就休眠不占 CPU,有事件再处理,再配合 sendfile 零拷贝,减少内核态用户态拷贝开销,所以能单机扛上万并发。默认用 epoll 边缘触发,减少重复事件通知。
4. Nginx 应用场景
口述: 第一,静态资源服务器,直接托管图片、JS、CSS; 第二,反向代理和负载均衡,做后端集群入口; 第三,动静分离,静态直接 Nginx 返回,动态请求转发给 Java、PHP 这类应用; 第四,HTTPS 证书卸载、HTTP/2; 第五,前置防护,限流、防盗链、黑白名单; 第六,HTTP 缓存,减轻后端压力,也常作为 API 网关前置。
5. 正向代理、反向代理
口述: 正向代理代理客户端,客户端知道代理存在,用来访问外网,服务端看不到真实客户,比如 VPN; 反向代理代理后端服务,用户无感知,用户访问 Nginx,Nginx 转发请求到后端集群,对外只暴露 Nginx,用来做负载均衡、隐藏后端节点,我们常用的就是反向代理。 一句话记:正向帮客户上网,反向帮服务器扛流量。
6. Nginx 负载均衡策略和场景
口述: 原生内置四种: 第一个默认轮询,按顺序分发,适合后端机器性能差不多、无状态服务; 第二个加权轮询,配置 weight,性能好的机器权重拉高,分到更多流量,适合硬件参差不齐的集群; 第三个 ip_hash,按客户端 IP 哈希,同一个 IP 固定打到同一台后端,用来做会话保持;缺点是后端扩容会打乱哈希; 第四个 least_conn 最少连接,优先分给当前活跃连接最少的节点,适合慢请求多、请求耗时差距大的业务。 另外 url_hash、fair 属于第三方模块,不是原生自带。
7. proxy_pass 末尾带 / 和不带 / 区别
口述: 一句话:带斜杠代表替换 location 匹配到的路径,不带斜杠代表直接拼接 URI。 举个最常见例子,location /api/,如果 proxy_pass 后面带 /,请求 /api/test,转发过去就是 /test;不带 /,转发就是 /api/test。面试最容易踩坑,写配置一定要区分。
8. Nginx 和后端 upstream 长连接 keepalive
口述: 这里要注意,这是 Nginx 到后端服务的长连接,不是浏览器到 Nginx 的。 首先在 upstream 里配置 keepalive,指定每个 worker 能维持的空闲长连接池数量;然后在 location 里必须写 proxy_http_version 1.1,同时把 Connection 头置空,不要把 close 传给后端。 作用是复用 TCP 连接,减少频繁建连断连的握手开销,提升吞吐量。
9. upstream 后端健康检查
口述: 开源版原生只有被动健康检查,靠 proxy_next_upstream,配合 max_fails 和 fail_timeout。只有请求打到节点失败了,才会统计失败次数,失败达到阈值,一段时间内不再分发流量;缺点是不会主动探测,必须流量进来才发现故障。 主动健康检查需要第三方 check 模块或者商业版 Nginx,会定时主动发包探测节点状态,故障节点直接下线。
10. Nginx 配置五大作用域
口述: 从外到内层级:全局 main 块、events 块、http 块、server 块、location 块。 main 全局块配置 worker 进程、日志、pid; events 配置连接数、epoll 事件模型; http 块放通用 http 配置、upstream、gzip; server 是虚拟主机,绑定端口和域名; location 在 server 内部,匹配 URI,控制路由、代理、静态资源。外层配置可以被子块继承,子块可以覆盖。
11. location 匹配优先级
口述: 优先级从高到低: 第一,= 精确匹配,最高; 第二,^~ 前缀匹配,命中之后直接走,不再匹配正则; 第三,~ 区分大小写正则、~* 不区分大小写正则;正则按书写顺序匹配,匹配第一个就停; 最后是普通前缀匹配,没有修饰符那种,遵循最长前缀优先。 口诀:精确 > ^~ > 正则 > 普通前缀最长匹配。
12. root 和 alias 区别
口述: root 是路径拼接,root 指定目录 + 请求 URI 拼出最终文件路径; alias 是替换 location 匹配的 uri,location 匹配到的部分直接替换成 alias 的目录。 举例子,location /test/,alias /data/html/,访问 /test/a.html,实际读 /data/html/a.html;换成 root,就读 /data/html/test/a.html。alias 一般末尾建议加斜杠,不建议直接在 location / 里用 alias。
13. 动静分离是什么,怎么实现
口述: 动静分离就是静态资源比如图片、JS、CSS 直接由 Nginx 本地返回,动态接口请求,像 Java 接口,反向代理转发给应用服务器。好处是减轻后端应用压力,Nginx 处理静态文件效率高。 实现上,用 location 正则匹配静态资源后缀,配置 root、expires 缓存;剩下动态请求走 proxy_pass 代理后端。
14. rewrite 和 redirect 区别,301/302
口述: rewrite 默认是 Nginx内部 URI 重写,浏览器地址不变,是内部跳转; redirect 或者 rewrite 加 redirect/permanent,是返回 3xx 外部重定向,浏览器收到状态码,重新发起请求,地址栏会变。 301 是永久重定向,浏览器会缓存跳转关系,适合域名永久迁移,SEO 权重转移; 302 是临时重定向,不缓存,适合临时活动、登录跳转。补充一点,301/302 老浏览器可能把 POST 转 GET,如果要保留请求方法用 307、308。
15. Nginx 高并发优化
口述: 首先进程,worker_processes 设 auto,等于 CPU 核心; events 块开大 worker_connections,启用 epoll、multi_accept; 系统层面调 ulimit 文件句柄、somaxconn; 开启 sendfile、tcp_nopush、tcp_nodelay 做零拷贝; 合理配置前后端 keepalive 复用连接; 静态资源加 expires 缓存、开启 gzip; 精简日志、必要时限流,关闭不需要的模块,减少开销。
16. Gzip 压缩
口述: gzip 就是 Nginx 对文本类响应做压缩再返回浏览器,减小传输体积、节省带宽、加速页面加载;图片视频这类本身压缩过的一般不开。 配置核心:gzip on,设置最小压缩长度、压缩级别,指定需要压缩的 MIME 类型,开启 gzip_vary。压缩级别推荐 6,平衡 CPU 消耗和压缩率,太高 CPU 开销大。
17. Keepalived+Nginx 高可用
口述: 典型主备 VIP 方案。两台 Nginx 服务器,装 Keepalived,共用一个虚拟 VIP 对外提供服务。 Keepalived 基于 VRRP 协议,主节点绑定 VIP,定时发心跳;主节点宕机,备节点自动抢占 VIP,实现故障漂移。一般还要写脚本检测 Nginx 进程,如果 Nginx 挂了,就让 Keepalived 主动释放 VIP 触发切换。注意这只是故障转移,如果没有 Redis 共享 session,会话会丢失。
18. Nginx 平滑重启、平滑升级
口述: 先分清两个场景: 第一个平滑 reload,只加载新配置,不换二进制。先 nginx -t 校验配置,再 nginx -s reload 或者发 HUP 信号。Master 拉起新 Worker 跑新配置,老 Worker 处理完已有连接退出,业务不断。 第二个平滑升级,替换 nginx 二进制程序。先备份旧程序,替换新版,发 USR2 信号,Master 启动一套新主进程 + Worker,新旧两套共存;再给旧 Master 发 WINCH,优雅关闭旧 Worker;验证没问题再杀掉旧 Master 完成升级。
19. HTTPS+HTTP/2 配置
口述: 在 server 里 listen 443 ssl http2,配置证书公钥和私钥路径;然后禁用老旧不安全的 TLS1.0、1.1,只保留 TLS1.2、TLS1.3,配置安全加密套件,优先服务端加密套件。 80 端口做 301 永久重定向,把 HTTP 全部跳 HTTPS。HTTP/2 可以多路复用,减少连接数,提升页面加载速度。
20. limit_req、limit_conn 防 CC
口述: limit_req 是请求速率限制,漏桶模型,控制每秒请求量,防接口高频 CC 攻击; limit_conn 是并发连接限制,控制单个 IP 同时建立的连接数量。 先在 http 块用 limit_req_zone、limit_conn_zone 定义共享内存区域,按二进制 remote_addr 区分 IP;location 里调用 zone,burst 做缓冲,nodelay 避免排队等待。用 $binary_remote_addr 比普通 ip 更省内存。
21. Referer 防盗链
口述: 原理就是校验请求头 Referer,只放行自己域名过来的资源访问,防止别人直接引用我们图片视频盗流量。 用 valid_referers 配置信任域名,none 允许直接地址栏访问、blocked 兼容代理隐藏 referer 的场景;如果不匹配,$invalid_referer 为 true,直接 return403。缺点是 Referer 头部可以伪造,高安全场景要配合签名 token。
22. 隐藏 Nginx 版本号
口述: 直接在 http 块配置 server_tokens off; 关闭之后,响应头 Server 字段不再输出具体版本号,只显示 nginx,避免攻击者根据版本针对性利用漏洞,是基础安全加固手段。
23. Nginx 日志类型、日志切割
口述: 两种核心日志:access 访问日志,记录每一次请求、状态码、耗时、IP;error 错误日志,记录启动异常、代理报错,分不同日志级别。 日志切割推荐系统自带 logrotate,按天轮转、压缩归档旧日志,切割后发 USR1 信号让 Nginx 重新打开日志文件。不能直接 rm 日志文件,Nginx 还持有文件句柄,磁盘空间不会释放,也可以写脚本配合 nginx -s reopen 实现。
24. LVS 和 Nginx 的区别
口述: LVS 和 Nginx 最核心的区别就是工作层级不一样。 LVS 是四层负载均衡,工作在传输层,基于 Linux 内核 ipvs 模块,只识别 IP + 端口,不解析 HTTP 协议,看不到 URL、header 这些内容。优点是内核态转发,性能极高、能扛超大并发;缺点是没有 HTTP 业务处理能力,健康检查比较简单,配置相对复杂。
Nginx 默认是七层负载均衡,工作在应用层,能完整解析 HTTP/HTTPS 请求,可以识别 URL、Cookie、请求头,支持 SSL 卸载、rewrite、缓存、限流、按 HTTP 状态码做健康检查这些业务能力。它是用户态进程,性能弱于 LVS,但配置简单、功能灵活。 Nginx 也可以通过 stream 模块做四层 TCP 代理,只不过四层场景下性能不如 LVS。