Skip to content

服务器运维面试题库 ​

生成时间:2026-05-21 22:15


【面试题】1. Nginx的upstream模块中,ip_hash和least_conn两种负载均衡策略分别适用什么场景?如果后端服务器性能不一致怎么办? ​

【标准答案】ip_hash根据客户端IP做哈希,保证同一IP始终打到同一后端,适合有会话状态但没做Session共享的场景,比如传统Java应用靠本地Session。least_conn把请求分给当前活跃连接数最少的后端,适合请求处理时间差异大的场景,比如文件上传、长连接,避免慢服务器雪崩。如果后端性能不一致,两种策略都可以配合weight参数使用,比如ip_hash+weight或者least_conn+weight,给性能强的机器更高权重。另外如果做了Session共享(Redis),就不需要ip_hash了,直接用least_conn或轮询+weight更合理。

【面试题】2. 请描述SSL/TLS握手的完整流程,以及Nginx中如何配置HTTPS并优化性能? ​

【标准答案】TLS握手流程(以TLS 1.2为例):客户端发Client Hello(支持的TLS版本、加密套件列表、随机数A)→服务端回Server Hello(选定TLS版本和加密套件、随机数B、服务器证书)→客户端验证证书链(逐级到根CA,检查有效期和域名)→客户端生成预主密钥,用服务器公钥加密发给服务端→双方用随机数A+B+预主密钥生成会话密钥→双方互发Finished消息确认。Nginx配置HTTPS核心:listen 443 ssl; ssl_certificate指定证书路径; ssl_certificate_key指定私钥路径。性能优化关键三点:一是ssl_session_cache shared:SSL:10m开启会话缓存,复用握手减少RTT;二是ssl_protocols TLSv1.2 TLSv1.3;禁用不安全版本;三是开启OCSP Stapling(ssl_stapling on),客户端不用自己去查证书状态,减少延迟。TLS 1.3已经把握手从2-RTT降到1-RTT,有条件尽量启用。

【面试题】3. Linux系统中load average三个数值分别代表什么?什么情况下load很高但CPU利用率很低?怎么排查? ​

【标准答案】load average三个数分别是1分钟、5分钟、15分钟内的平均负载,代表系统中处于运行状态(R)和不可中断等待状态(D)的进程数之和。load很高但CPU利用率很低,典型原因是大量进程处于D状态——也就是在等IO,最常见的是磁盘IO瓶颈。排查步骤:先用top看cpu的wa(iowait)指标是不是很高,如果是,再用iostat -x 1看各磁盘的%util和await,%util接近100%说明磁盘扛不住了;用iotop或者pidstat -d找出哪个进程在疯狂写盘。另外一种可能是网络IO阻塞,比如NFS挂载卡住,用nfsstat或检查mount状态。还有一种场景是大量短生命周期的进程排队,用ps aux | grep D看D状态进程。解决方案视原因定:磁盘慢就换SSD或加缓存,进程太多就限流或优化代码,NFS问题就加超时参数。

【面试题】4. Tomcat的Connector线程模型NIO、APR、NIO2有什么区别?生产环境怎么选? ​

【标准答案】NIO是Tomcat 8+默认模型,基于Java NIO,用少量线程通过Selector管理大量连接,适合普通Web应用,性能不错且无需额外依赖。APR用Apache Portable Runtime,底层是C实现的native库,通过JNI调用,在SSL处理和静态文件上性能最优,但需要额外安装APR库和OpenSSL,部署维护成本高。NIO2基于Java 7的AsynchronousFileChannel,是真正的异步IO,理论上适合大量长连接场景,但实际生产中相比NIO提升有限,某些场景甚至不如NIO稳定。生产环境建议:绝大多数场景用NIO就够了,简单稳定;如果对SSL性能有极致要求且运维能力强,考虑APR;NIO2目前用的人少,不推荐作为首选。配置方式:server.xml中Connector的protocol属性,NIO对应org.apache.coyote.http11.Http11NioProtocol,APR对应Http11AprProtocol。

【面试题】5. 服务器出现502 Bad Gateway错误,请给出系统的排查思路和常见原因。 ​

【标准答案】502说明Nginx作为反向代理时,收到了上游服务器无效或无法理解的响应。排查分四步走:第一步看Nginx错误日志error_log,找upstream相关报错,常见关键信息有"Connection refused"(上游没起来)、"upstream timed out"(上游响应超时);第二步检查上游服务状态,curl直接请求上游端口看通不通,systemctl看服务是否running,如果是PHP-FPM就检查php-fpm进程数是否打满了pm.max_children;第三步检查系统资源,free看内存是否耗尽导致OOM Kill,df看磁盘是否满了,ulimit -n看文件描述符是否不够;第四步看网络连通性,防火墙是否挡了、SELinux是否拦截、上游是否只监听了localhost。最常见的原因:后端服务挂了、FPM进程池满了、后端响应超时(proxy_read_timeout默认60s,慢接口需要调大)、上游服务OOM被杀。修复后记得检查root cause防止复现。

【面试题】6. Keepalived+Nginx实现高可用的原理是什么?脑裂问题如何解决? ​

【标准答案】Keepalived基于VRRP协议实现虚拟IP漂移。两台Nginx服务器配成主备,Keepalived通过组播发送VRRP通告,Master持有VIP对外提供服务,Backup监听通告。Master故障时Backup收不到通告,自动接管VIP,实现故障转移。检测脚本配置vrrp_script,周期性检查Nginx进程是否存在(比如killall -0 nginx),检测失败则主动降低优先级触发切换。脑裂是指Master和Backup都认为自己是主,同时持有VIP,原因是VRRP通告不通——常见于交换机故障、防火墙拦截组播、网络抖动。解决方案:一是用iptables严格限制VRRP只允许对端IP;二是配置仲裁机制,同时检测网关是否可达,网关不可达则不抢占VIP;三是监控报警,写脚本周期性检测是否有两台同时持有VIP;四是生产环境建议用单播模式(unicast_peer)替代组播,更可控。另外防火墙要放行VRRP协议(IP协议号112)。

【面试题】7. 如何用iptables/firewalld配置一套Web服务器的防火墙规则?写出关键规则。 ​

【标准答案】iptables方案:首先设默认策略为DROP,iptables -P INPUT DROP; iptables -P FORWARD DROP; iptables -P OUTPUT ACCEPT。然后放行回包:iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT。放行lo:iptables -A INPUT -i lo -j ACCEPT。放行业务端口:iptables -A INPUT -p tcp --dport 80 -j ACCEPT; iptables -A INPUT -p tcp --dport 443 -j ACCEPT。放行SSH(建议改端口):iptables -A INPUT -p tcp --dport 2222 -s 办公网段 -j ACCEPT,限制来源IP。放行ping:iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT。日志记录丢弃包:iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "。最后iptables-save保存规则。firewalld方案更简单:firewall-cmd --permanent --add-service=http; firewall-cmd --permanent --add-service=https; firewall-cmd --permanent --add-port=2222/tcp; firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="办公网段" port port="2222" protocol="tcp" accept'; firewall-cmd --reload。关键原则:最小放行、SSH限源、默认拒绝、规则持久化。

【面试题】8. Prometheus+Grafana监控体系中,如何设计一套Nginx服务的监控指标和告警规则? ​

【标准答案】监控指标设计分三层:基础层用node_exporter采集CPU、内存、磁盘IO、网络流量、文件描述符使用率;Nginx层用nginx-prometheus-exporter采集stub_status的活跃连接数(nginx_connections_active)、接受/处理请求数、读写等待数;业务层通过自定义日志分析或lua插件采集QPS、响应时间P99、状态码分布(4xx/5xx比例)、upstream响应时间。告警规则设计:关键告警——Nginx进程down(up == 0持续1m)、5xx错误率超过5%(持续3m)、upstream响应超时率升高;重要告警——活跃连接数超过worker_connections的80%、CPU使用率超85%持续5m、磁盘使用率超90%;预警告警——QPS突增超历史均值2倍(可能CC攻击)、P99延迟持续升高。通知渠道建议:关键告警电话+企微,重要告警企微+邮件,预警告警邮件。Grafana仪表盘建议三个视图:总览(大盘看全貌)、单机详情(下钻排查)、告警历史(回溯分析)。记得给Nginx配stub_status:location /stub_status { stub_status; access_log off; allow 监控IP; deny all; }。

【面试题】9. Docker容器资源限制怎么做?一个容器把宿主机内存吃光了怎么处理? ​

【标准答案】Docker资源限制通过docker run参数设置:内存限制-m 512m --memory-swap 1g(swap=内存+swap总量,设成和-m一样等于禁swap);CPU限制--cpus=1.5(最多用1.5核)或--cpuset-cpus=0,2(绑核);IO限制--device-write-bps /dev/sda:10mb。容器吃光宿主机内存的原因:一是没设资源限制,容器默认不限;二是设了-m但程序mmap大量内存绕过了限制;三是OOM时Docker默认杀容器,但如果--oom-kill-disable=true就不杀,内存会持续占用。处理方案:首先给所有容器设置合理的-m和--memory-swap,这是基本纪律;其次设--oom-score-adj调整OOM优先级,关键服务设低值避免被优先杀;第三在K8s中用requests和limits明确资源范围,QoS等级Guaranteed最稳定;第四监控层面用cAdvisor采集容器内存使用,配告警在达到limit 80%时预警。已经吃光的情况:docker stats找到问题容器,docker kill快速止损,分析日志找root cause,调整内存限制后重启。

【面试题】10. 动静分离架构怎么设计?Nginx如何配置实现静态资源与动态请求的分离处理? ​

【标准答案】动静分离核心思想:静态资源(JS/CSS/图片/字体)由Nginx直接处理或CDN边缘节点返回,动态请求(API/页面渲染)转发给后端应用服务器。Nginx配置实现:用location匹配规则分离,location ~* .(js|css|png|jpg|jpeg|gif|ico|woff2|svg)$ { root /data/static; expires 30d; add_header Cache-Control "public, immutable"; }匹配静态资源走本地文件+长缓存;location /api/ { proxy_pass http://upstream_backend; proxy_set_header X-Real-IP $remote_addr; }动态请求转发后端。进一步优化:静态资源上CDN,Nginx只做回源;开启gzip压缩文本类资源;配open_file_cache缓存文件描述符减少系统调用。架构层面:前端打包后部署到Nginx或OSS/CDN,后端只提供API,彻底解耦。动静分离的好处:Nginx处理静态文件极快(sendfile零拷贝),后端只处理业务逻辑,减少应用服务器压力;静态资源CDN加速后用户就近获取,体验更好;缓存策略清晰,静态长缓存+动态不缓存,不存在缓存污染问题。