服务器运维面试题库
生成时间:2026-05-22 22:58
【面试题】1. Nginx的upstream健康检查有哪几种方式?被动检查和主动检查分别怎么配置,生产环境推荐哪种?
【标准答案】 Nginx原生支持的是被动健康检查,通过upstream模块的max_fails和fail_timeout参数实现。配置示例:server 192.168.1.10 max_fails=3 fail_timeout=30s;,含义是30秒内连续3次失败就标记为不可用,30秒后再次尝试。这是Nginx开源版自带的,不需要额外模块。
主动健康检查需要用第三方模块nginx_upstream_check_module(淘宝开源),配置:check interval=3000 rise=2 fall=3 timeout=1000 type=http;,含义是每3秒主动发一次HTTP探测,连续2次成功恢复,连续3次失败摘除。
生产环境推荐主动检查+被动检查组合:主动检查能第一时间发现故障并摘除,被动检查作为兜底。如果只用开源版Nginx,至少把被动检查的参数调优——max_fails设2-3,fail_timeout别太长(10-30秒),否则故障节点恢复慢。另外要注意,被动检查只对当前worker进程生效,不是全局共享状态。
【面试题】2. Linux中load average的三个数字分别代表什么?load average很高但CPU使用率不高,可能是什么原因?
【标准答案】 load average的三个数字分别是1分钟、5分钟、15分钟内的系统平均负载,即处于可运行状态(R)和不可中断睡眠状态(D)的进程数的指数移动平均。简单说就是"排队等CPU的进程数+等磁盘IO的进程数"。
对于多核系统,load值除以CPU核心数才是真正的负载比。比如4核机器load=4,其实每个核才100%负载,不算过载。
load高但CPU使用率不高,典型原因是:
- 磁盘IO瓶颈——大量进程处于D状态(uninterruptible sleep),在等磁盘读写完成,最常见。用
iostat -x 1看%util和await确认 - NFS/网络存储卡住——等远程存储响应,进程也进D状态
- 内存不足导致swap颠簸——频繁换页,进程等IO
排查思路:top里看wa(iowait)占比,vmstat 1看b列(D状态进程数),iostat -x 1看哪块盘慢。定位到具体进程用iotop或pidstat -d。
【面试题】3. Tomcat的NIO、APR、NIO2三种Connector有什么区别?生产环境怎么选?
【标准答案】 三种Connector的核心区别在于底层IO模型:
BIO(已废弃):一个请求一个线程,8.5后已移除,不再讨论。
NIO:基于Java NIO,用少量Acceptor线程接受连接,Poller线程(默认2个)轮询事件,Worker线程池处理业务。非阻塞IO,少量线程管理大量连接。配置:protocol="org.apache.coyote.http11.Http11NioProtocol",这是Tomcat 8.5+的默认值。
APR:基于Apache Portable Runtime,用C语言实现的本地库,底层用操作系统的epoll/sendfile等系统调用,性能最优。静态文件走sendfile零拷贝,SSL走OpenSSL原生加速。配置:protocol="org.apache.coyote.http11.Http11AprProtocol",需要安装libtcnative库。
NIO2:基于Java 7的Asynchronous IO,真正的异步IO模型,用CompletionHandler回调。配置:protocol="org.apache.coyote.http11.Http11Nio2Protocol"。
生产环境选择:优先APR(性能最好,但需装native库);如果不方便装native库,用NIO(开箱即用,性能够用,也是默认);NIO2在Linux上相比NIO提升不明显,Windows上表现更好,一般Linux生产不选。实测APR比NIO高15-25%的吞吐,尤其SSL场景差距更大。
【面试题】4. 502和504错误分别代表什么?在Nginx反向代理场景下,各自的排查思路是什么?
【标准答案】 502 Bad Gateway:Nginx作为代理,收到了上游服务器的响应,但这个响应是无效的。常见原因:上游服务崩溃、端口没起来、返回了不符合HTTP协议的内容、upstream过早关闭连接。排查步骤:①先看后端服务是否存活(curl localhost:port或systemctl status);②查Nginx error.log里的upstream相关报错;③如果是PHP-FPM,检查pm.max_children是否打满、进程是否全挂;④检查后端是否超时但返回了残缺响应。
504 Gateway Timeout:Nginx等上游响应超时了,上游没在规定时间内返回。常见原因:后端处理慢(慢SQL、外部API调用超时、GC停顿)、Nginx的proxy_read_timeout设太小。排查步骤:①查Nginx error.log确认是哪个timeout触发的(connect/read/send);②到后端服务器看应用日志,找到对应时间段的慢请求;③如果是偶发,看后端是否在GC或CPU打满;④调整timeout参数:proxy_connect_timeout 5s; proxy_read_timeout 60s;,但治标不治本,根本还是要优化后端性能。
关键区别:502是后端给了但给的不对,504是后端没给(超时了)。
【面试题】5. iptables和firewalld有什么区别?生产服务器用哪个好?写一条只允许10.0.0.0/8网段访问22端口的规则。
【标准答案】 iptables:直接操作内核netfilter的规则链,按顺序匹配,规则多时效率低(线性遍历)。配置分散在多张表(filter/nat/mangle/raw),理解门槛高但灵活。规则不持久化,重启丢失需配合iptables-save/restore。
firewalld:Red Hat系7+默认防火墙,底层仍调netfilter/iptables(或nftables)。引入了zone(区域)和service(服务)的概念,用XML配置,规则变更可动态生效不需重载所有规则。支持rich rule做复杂匹配,底层用nftables时性能更好(哈希查找)。
生产选哪个:CentOS 7+/RHEL 8+推荐firewalld,管理更方便、动态生效不中断连接;如果团队熟悉iptables且规则固定,iptables也完全OK;Ubuntu默认用ufw(底层也是iptables/nftables),看团队习惯。
规则示例:
iptables方式:
iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROPfirewalld方式:
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="ssh" accept'
firewall-cmd --permanent --zone=public --remove-service=ssh
firewall-cmd --reload注意要先加允许规则再删默认开放,别把自己锁外面了。
【面试题】6. Nginx的proxy_cache和fastcgi_cache分别用在什么场景?缓存命中率低怎么优化?
【标准答案】 proxy_cache:缓存上游服务器的HTTP响应,适用于Nginx作为反向代理的场景(后端是Tomcat、Node.js等任意HTTP服务)。配置关键:proxy_cache_path /data/cache levels=1:2 keys_zone=mycache:100m max_size=10g inactive=60m;,然后在location里proxy_cache mycache; proxy_cache_valid 200 302 10m;。
fastcgi_cache:专门缓存FastCGI协议的响应,场景是Nginx+PHP-FPM。配置类似但用fastcgi_cache指令,key通常包含$request_method$scheme$host$request_uri。
缓存命中率优化:
- Key设计要合理——避免把
$cookie_xxx等频繁变化的变量加入key,否则同一内容生成大量缓存副本,命中率骤降 - inactive时间设对——太短热点内容过期快,太长冷内容占空间。按业务访问模式调整
- 分级过期——
proxy_cache_valid 200 10m; 404 1m;不同状态码不同过期时间 - 加缓存状态头——
add_header X-Cache-Status $upstream_cache_status;,用这个header统计命中率:HIT/MISS/EXPIRED/Stale - stale缓存兜底——
proxy_cache_use_stale error timeout updating;,后端异常时返回过期缓存而不是502 - 缓存预热——重启后缓存为空,主动爬取热点URL填充
- levels=1:2——两级目录避免单目录文件过多影响文件系统性能
【面试题】7. 说一下SSL/TLS握手流程,以及Nginx中如何配置HTTPS优化性能?
【标准答案】 TLS 1.2握手流程(以RSA密钥交换为例):
- Client Hello:客户端发送支持的TLS版本、加密套件列表、随机数R1
- Server Hello:服务端选择TLS版本和加密套件,返回随机数R2
- Certificate:服务端发证书链
- Server Hello Done:服务端结束
- Client Key Exchange:客户端生成预主密钥,用服务端公钥加密发送
- Change Cipher Spec:客户端通知后续用协商的密钥加密
- Finished:客户端发验证消息
- Change Cipher Spec + Finished:服务端同样流程
双方用R1+R2+预主密钥算出会话密钥,后续对称加密通信。整个过程2-RTT。
TLS 1.3优化为1-RTT:Client Hello时带上key share直接推测密钥,服务端回Server Hello时已完成密钥协商。还支持0-RTT恢复(用PSK)。
Nginx HTTPS性能优化:
ssl_session_cache shared:SSL:10m; # 会话缓存,复用避免重复握手
ssl_session_timeout 1d; # 缓存1天
ssl_session_tickets on; # Session Ticket,无状态复用
ssl_protocols TLSv1.2 TLSv1.3; # 禁用旧版本
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; # 优先ECDHE
ssl_prefer_server_ciphers on; # 服务端优先选择
ssl_ecdh_curve X25519:P-256; # 最快的ECDH曲线
keepalive_timeout 75s; # 长连接复用,减少握手关键点:会话复用是最大的优化项,session_cache对同一客户端再次访问可省掉完整握手;启用TLS1.3省一个RTT;ECDHE比RSA密钥交换快且支持PFS前向保密;OCSP Stapling避免客户端单独查询证书状态。
【面试题】8. LVS的NAT、DR、TUN三种模式原理和适用场景分别是什么?
【标准答案】 NAT模式:客户端请求到Director(调度器),Director改写目标IP为RealServer IP转发;RealServer响应回Director,Director再改写源IP回客户端。请求和响应都过Director,Director容易成为瓶颈。优点:RealServer可以是任意OS,不用改配置。适用于小规模集群(10-20台以内)。
DR模式(Direct Routing):Director只处理请求,不改IP,改MAC地址直接转发到同网段RealServer;RealServer直接把响应发回客户端(绕过Director)。只有请求过Director,响应不过,吞吐量高。要求:Director和RealServer在同一物理网段,RealServer需配置VIP在lo口上且抑制ARP响应(arp_ignore=1, arp_announce=2)。适用于大规模高性能场景,是最常用的模式。
TUN模式(IP隧道):Director把请求封装在IP隧道里转发,RealServer解隧道处理后直接响应客户端。请求和响应可以走不同路径,RealServer可以跨网段甚至跨地域。要求RealServer支持IP隧道协议。适用于异地多活、跨机房调度。
选型建议:同机房同网段用DR(性能最好,最主流);跨网段/跨机房用TUN;小规模或RealServer不好改配置时用NAT。性能排序:DR > TUN > NAT。
【面试题】9. 服务器磁盘满了怎么紧急处理?给出完整的排查和处理步骤。
【标准答案】 第一步:确认哪个分区满了df -h查看各分区使用率,找到100%的分区。
第二步:定位大文件/大目录
du -sh /* 2>/dev/null | sort -rh | head -20 # 根分区
du -sh /var/log/* | sort -rh | head -10 # 日志目录快速定位法:lsof +L1找已删除但仍被进程占用的文件——这是最容易被忽略的:文件rm了但进程还持有fd,空间不会释放。
第三步:紧急释放空间
- 日志文件:
> /var/log/xxx.log清空(用>而不是rm,不中断写入进程) - 已删除但被占用的:
kill -HUP <pid>或重启对应服务释放fd - 临时文件:
rm -rf /tmp/old_*、rm -rf /var/cache/xxx - Docker:
docker system prune -a清理无用镜像和容器
第四步:确认释放成功 再次df -h确认空间恢复。
第五步:长期治本
- 日志加logrotate自动轮转:
/etc/logrotate.d/配置按天/大小切割 - 设置监控告警:磁盘使用率>85%告警
- 检查是否有定时任务在写大量临时文件没清理
- 考虑扩容或迁移数据到更大的存储
避坑:不要直接rm正在写入的日志文件!用> file截断或cp /dev/null file清空,否则进程fd不断开空间不释放。如果已经rm了,lsof | grep deleted找占用进程,重启它。
【面试题】10. Prometheus的Pull模型和Zabbix的Push模型各有什么优劣?什么场景下选哪个?
【标准答案】 Prometheus Pull模型:服务端主动去拉取targets的/metrics接口。优势:①服务端掌控采集频率和节奏,不会因客户端配置错误导致服务端被打爆;②天然支持服务发现(K8s中自动发现Pod);③客户端只需暴露HTTP接口,实现简单;④方便做本地调试(直接curl /metrics看数据)。劣势:①大规模时服务端拉取压力大(可分区缓解);②不适合短生命周期任务(任务结束后来不及拉);③跨网络需确保服务端可达所有目标(可用Pushgateway中转)。
Zabbix Push模型(Agent主动模式):Agent主动向Server发送数据。优势:①客户端主动上报,不怕NAT/防火墙阻隔;②适合大规模分布式环境,Server端压力分散;③短生命周期任务完成时立即上报。劣势:①客户端配置复杂(要配Server地址、频率);②客户端配错可能打爆Server;③服务发现弱,需要自动注册或手动配置。
选型建议:
- Kubernetes/云原生环境→选Prometheus,服务发现、Grafana生态、PromQL查询都是天然适配
- 传统IDC/混合环境、跨NAT网络→Zabbix更省心,Agent主动上报不怕网络拓扑
- 大规模+云原生→Prometheus + Thanos/Cortex做长期存储和联邦查询
- 已有Zabbix且运行稳定→没必要迁移,Zabbix 6+也支持Prometheus远程写入,可以共存
- 最佳实践:新项目云原生用Prometheus,传统环境用Zabbix,用Remote Write打通数据
两个不是二选一的关系,很多企业是双栈运行:基础设施用Zabbix(网络设备、操作系统),应用层用Prometheus(微服务、K8s)。