服务器运维面试题库(带答案)
生成时间:2026-05-21 22:56
【面试题】1. Nginx的location匹配规则有哪些?匹配优先级是怎样的?
【标准答案】 Nginx的location匹配有四种方式,优先级从高到低:
- 精确匹配
location = /path— 优先级最高,URI完全一致才命中,常用于首页或特定接口 - 前缀匹配(^~)
location ^~ /path— 匹配后不再检查正则,适合静态资源路径 - 正则匹配
location ~ /path(区分大小写)或location ~* /path(不区分大小写)— 按配置文件中的顺序,先匹配到的生效 - 普通前缀匹配
location /path— 优先级最低,当前面都不匹配时才用
面试官追问怎么记?一句话:精确 > ^~前缀 > 正则(按顺序) > 普通前缀。实际配置中,API接口用精确匹配,静态资源用^~前缀,动态路由用正则,剩下的兜底走普通前缀。
【面试题】2. Tomcat的Connector有哪些线程模型?生产环境怎么选?
【标准答案】 Tomcat Connector有三种线程模型:
- BIO(Blocking I/O) — Tomcat 8.5之前默认,一个连接一个线程,并发高时线程数爆炸,性能差,已淘汰
- NIO(Non-blocking I/O) — Tomcat 8.5+默认,基于Java NIO,用少量线程处理大量连接,通过Poller线程轮询事件,适合大多数场景
- APR(Apache Portable Runtime) — 调用本地C库实现,性能最强,但需要安装APRnative库,部署复杂
生产环境选择:一般用NIO就够了,配置简单性能好。如果对性能要求极致且能接受额外依赖,用APR。BIO千万别用。
关键调优参数:maxThreads(最大工作线程,默认200,CPU密集型适当降低,IO密集型可调到300-500)、acceptCount(全连接队列长度,默认100)、maxConnections(最大连接数,NIO默认10000)。
【面试题】3. Linux系统load average很高但CPU使用率不高,可能是什么原因?怎么排查?
【标准答案】 Load average反映的是系统中处于运行态(R)和不可中断睡眠态(D)的进程数。CPU使用率不高但load高,大概率是IO瓶颈。
排查步骤:
top或htop看load和CPU使用率确认现象iostat -x 1看磁盘IO,重点看%util和await,util接近100%或await飙高就是磁盘IO瓶颈vmstat 1看wa(IO wait)列,wa高说明CPU在等IOps aux | awk '$8 ~ /D/'找出D状态的进程iotop定位具体哪个进程在大量读写磁盘
常见原因:磁盘性能差(机械盘)、大量小文件读写、数据库慢查询打满IO、NFS网络存储延迟高。
解决方案:换SSD、优化查询减少IO、调整内核参数(如dirty_ratio)、把IO密集型业务拆到不同磁盘。
【面试题】4. Nginx做负载均衡时,upstream的健康检查怎么配?被动检查和主动检查有什么区别?
【标准答案】 Nginx原生只支持被动健康检查,通过upstream模块参数配置:
upstream backend {
server 192.168.1.1:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.2:8080 max_fails=3 fail_timeout=30s;
}max_fails:在fail_timeout时间内失败次数达到该值,标记为不可用fail_timeout:标记不可用后暂停时间,过后会再次尝试
被动检查的问题是:只有流量经过时才能发现后端挂了,没有流量时感知不到。
主动健康检查需要用第三方模块nginx_upstream_check_module或商业版Nginx Plus:
upstream backend {
server 192.168.1.1:8080;
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
}每隔3秒主动发请求检测,连续2次成功标记恢复,连续3次失败标记不可用。
生产环境推荐:主动健康检查 + 被动检查双保险,主动检查能第一时间发现问题,被动检查做兜底。
【面试题】5. 服务器出现502 Bad Gateway错误,如何系统性排查?
【标准答案】 502说明Nginx作为代理,收到了上游服务的无效响应。排查按这个顺序:
- 查上游服务是否存活:
systemctl status xxx或ps aux | grep xxx,服务挂了直接重启 - 查上游端口是否监听:
ss -tlnp | grep 端口号,端口没在监听说明服务启动失败 - 查Nginx错误日志:
tail -f /var/log/nginx/error.log,找具体报错信息Connection refused→ 上游没启动或端口不对Connection timed out→ 上游响应太慢或网络不通upstream prematurely closed connection→ 上游崩溃断连
- 查上游服务日志:看Java/PHP等服务日志有没有OOM、线程池满等错误
- 查系统资源:
free -m看内存是否耗尽,df -h看磁盘是否满了
常见原因排序:上游服务挂了(60%)→ 上游响应超时(20%)→ 上游服务OOM崩溃(10%)→ Nginx和上游之间网络问题(5%)→ 其他(5%)。
【面试题】6. SSL/TLS握手流程是怎样的?如何在Nginx上优化HTTPS性能?
【标准答案】 TLS握手流程(以TLS 1.2为例):
- Client Hello:客户端发送支持的TLS版本、加密套件列表、随机数
- Server Hello:服务端选择TLS版本和加密套件,返回随机数和证书
- 证书验证:客户端验证服务端证书链
- 密钥交换:客户端生成预主密钥,用服务端公钥加密发送
- 双方计算对称密钥,切换到加密通信
- TLS 1.3简化到1-RTT,甚至0-RTT(恢复会话时)
Nginx HTTPS性能优化:
ssl_session_cache shared:SSL:10m; # 会话缓存,避免重复握手
ssl_session_timeout 1d; # 会话超时时间
ssl_session_tickets on; # Session Ticket,无状态恢复
ssl_protocols TLSv1.2 TLSv1.3; # 只开安全版本
ssl_prefer_server_ciphers on; # 服务端优先选择加密套件
ssl_ciphers HIGH:!aNULL:!MD5; # 只用高强度加密
keepalive_timeout 75s; # 长连接复用,减少握手关键点:TLS 1.3比1.2少一次RTT,能开就开;Session缓存让同一客户端短时间重连不用重新握手,这是最大的性能提升点;OCSP Stapling减少证书验证延迟;HTTP/2多路复用也能减少连接数间接优化。
【面试题】7. Keepalived+Nginx实现高可用的原理是什么?脑裂问题怎么解决?
【标准答案】 Keepalived基于VRRP协议实现高可用:
- 两台Nginx服务器分别安装Keepalived,一主一备
- 主节点拥有虚拟IP(VIP),对外提供服务
- 主节点定期发送VRRP通告,备节点监听
- 主节点故障时,备节点收不到通告,抢占VIP,接管流量
- 主节点恢复后可以抢回VIP(默认抢占模式)
配置要点:vrrp_instance定义角色和优先级,virtual_ipaddress配置VIP,track_script关联健康检查脚本。
脑裂问题:主备之间网络不通但都活着,两边都认为自己是主,都绑定VIP,导致IP冲突。
解决方案:
- 增加仲裁机制:引入第三台机器或网关做仲裁,只有两票才切换
- 检测网关通断:健康检查脚本同时检测对端和网关,网关不通则主动降级
- 使用多播+单播混合:
unicast_peer指定对端IP,减少多播风暴 - 防火墙规则:iptables限制VIP地址的ARP响应只在一台生效
- 监控告警:两边同时有VIP立即告警,人工介入
生产最实用的是检测网关+监控告警组合。
【面试题】8. Linux服务器如何做SSH安全加固?列出关键措施。
【标准答案】 SSH加固是服务器安全的第一道防线,关键措施:
- 禁用root远程登录:
PermitRootLogin no - 禁用密码认证,只用密钥:
PasswordAuthentication no,PubkeyAuthentication yes - 改默认端口:
Port 2222,避开自动化扫描 - 限制登录用户:
AllowUsers deploy admin,白名单方式 - 设置登录超时:
ClientAliveInterval 300,ClientAliveCountMax 2,5分钟无操作踢下线 - 禁用空密码:
PermitEmptyPasswords no - 限制登录尝试:
MaxAuthTries 3 - 配置Fail2ban:多次失败自动封IP
[sshd]
enabled = true
maxretry = 3
bantime = 3600- 使用堡垒机:所有SSH通过堡垒机跳转,统一审计
- 关闭GSSAPI认证:
GSSAPIAuthentication no,避免登录卡顿
额外建议:密钥用ed25519比rsa更安全更短;用ssh-agent管理密钥免频繁输密码;定期轮换密钥对。
【面试题】9. Prometheus+Grafana监控体系怎么搭建?核心概念是什么?
【标准答案】 核心概念:
- Metric:监控指标,如cpu_usage、memory_free
- Label:指标的维度标签,如
method="GET", path="/api" - Exporter:数据采集器,暴露/metrics接口供Prometheus拉取
- PromQL:Prometheus查询语言,用于查询和聚合数据
- Job/Instance:采集目标和实例
搭建流程:
- 部署Prometheus:配置
prometheus.yml定义scrape_targets
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['192.168.1.1:9100', '192.168.1.2:9100']- 部署Exporter:node_exporter采集系统指标,应用暴露自定义metrics
- 部署Grafana:添加Prometheus数据源,导入Dashboard(如Node Exporter Full)
- 配置告警:Prometheus的alert_rules.yml定义规则,Alertmanager发通知
- alert: HighCPU
expr: 100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 80
for: 5m
labels:
severity: warning- Alertmanager配置通知:支持邮件、钉钉、企业微信、Webhook
关键设计原则:Pull模式(Prometheus主动拉取)比Push更可靠,目标挂了自然拉不到;指标命名规范用namespace_subsystem_name格式;合理设置scrape_interval(默认15s)和retention时间(默认15天)。
【面试题】10. Docker容器资源限制怎么配?一个容器OOM被kill了怎么排查?
【标准答案】 Docker资源限制参数:
docker run -d \
--memory=512m \ # 内存上限
--memory-swap=1g \ # 内存+Swap上限
--cpus=1.5 \ # CPU核数限制
--cpu-shares=512 \ # CPU权重(相对值)
--pids-limit=100 \ # 进程数限制
--oom-kill-disable=false \ # 不禁用OOM Killer
nginxdocker-compose写法:
services:
app:
mem_limit: 512m
cpus: 1.5
deploy:
resources:
limits:
memory: 512M
cpus: '1.5'容器OOM排查步骤:
dmesg | grep -i oom查内核日志,确认OOM Killer触发及目标进程docker inspect <container> | grep -A5 State看OOMKilled字段是否为truedocker stats --no-stream <container>看当前内存使用- 查容器日志
docker logs <container>看应用报错 - 进入容器
docker exec -it <container> sh,看进程内存占用ps aux --sort=-%mem
常见原因:内存限制太小(Java应用JVM堆+元空间+堆外内存远超预期)、内存泄漏、缓存没做上限、JVM没设置-Xmx导致堆无限膨胀。
解决方案:调大内存限制、JVM加-Xmx -Xms -XX:MaxMetaspaceSize、修复内存泄漏代码、加监控告警(docker stats或cAdvisor)。