Skip to content

服务器运维面试题库(带答案) ​

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


【面试题】1. Nginx的location匹配规则有哪些?匹配优先级是怎样的? ​

【标准答案】 Nginx的location匹配有四种方式,优先级从高到低:

  1. 精确匹配 location = /path — 优先级最高,URI完全一致才命中,常用于首页或特定接口
  2. 前缀匹配(^~) location ^~ /path — 匹配后不再检查正则,适合静态资源路径
  3. 正则匹配 location ~ /path(区分大小写)或 location ~* /path(不区分大小写)— 按配置文件中的顺序,先匹配到的生效
  4. 普通前缀匹配 location /path — 优先级最低,当前面都不匹配时才用

面试官追问怎么记?一句话:精确 > ^~前缀 > 正则(按顺序) > 普通前缀。实际配置中,API接口用精确匹配,静态资源用^~前缀,动态路由用正则,剩下的兜底走普通前缀。


【面试题】2. Tomcat的Connector有哪些线程模型?生产环境怎么选? ​

【标准答案】 Tomcat Connector有三种线程模型:

  1. BIO(Blocking I/O) — Tomcat 8.5之前默认,一个连接一个线程,并发高时线程数爆炸,性能差,已淘汰
  2. NIO(Non-blocking I/O) — Tomcat 8.5+默认,基于Java NIO,用少量线程处理大量连接,通过Poller线程轮询事件,适合大多数场景
  3. 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瓶颈。

排查步骤:

  1. top或htop看load和CPU使用率确认现象
  2. iostat -x 1看磁盘IO,重点看%util和await,util接近100%或await飙高就是磁盘IO瓶颈
  3. vmstat 1看wa(IO wait)列,wa高说明CPU在等IO
  4. ps aux | awk '$8 ~ /D/' 找出D状态的进程
  5. iotop定位具体哪个进程在大量读写磁盘

常见原因:磁盘性能差(机械盘)、大量小文件读写、数据库慢查询打满IO、NFS网络存储延迟高。

解决方案:换SSD、优化查询减少IO、调整内核参数(如dirty_ratio)、把IO密集型业务拆到不同磁盘。


【面试题】4. Nginx做负载均衡时,upstream的健康检查怎么配?被动检查和主动检查有什么区别? ​

【标准答案】 Nginx原生只支持被动健康检查,通过upstream模块参数配置:

nginx
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:

nginx
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作为代理,收到了上游服务的无效响应。排查按这个顺序:

  1. 查上游服务是否存活:systemctl status xxx 或 ps aux | grep xxx,服务挂了直接重启
  2. 查上游端口是否监听:ss -tlnp | grep 端口号,端口没在监听说明服务启动失败
  3. 查Nginx错误日志:tail -f /var/log/nginx/error.log,找具体报错信息
    • Connection refused → 上游没启动或端口不对
    • Connection timed out → 上游响应太慢或网络不通
    • upstream prematurely closed connection → 上游崩溃断连
  4. 查上游服务日志:看Java/PHP等服务日志有没有OOM、线程池满等错误
  5. 查系统资源:free -m看内存是否耗尽,df -h看磁盘是否满了

常见原因排序:上游服务挂了(60%)→ 上游响应超时(20%)→ 上游服务OOM崩溃(10%)→ Nginx和上游之间网络问题(5%)→ 其他(5%)。


【面试题】6. SSL/TLS握手流程是怎样的?如何在Nginx上优化HTTPS性能? ​

【标准答案】 TLS握手流程(以TLS 1.2为例):

  1. Client Hello:客户端发送支持的TLS版本、加密套件列表、随机数
  2. Server Hello:服务端选择TLS版本和加密套件,返回随机数和证书
  3. 证书验证:客户端验证服务端证书链
  4. 密钥交换:客户端生成预主密钥,用服务端公钥加密发送
  5. 双方计算对称密钥,切换到加密通信
  6. TLS 1.3简化到1-RTT,甚至0-RTT(恢复会话时)

Nginx HTTPS性能优化:

nginx
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冲突。

解决方案:

  1. 增加仲裁机制:引入第三台机器或网关做仲裁,只有两票才切换
  2. 检测网关通断:健康检查脚本同时检测对端和网关,网关不通则主动降级
  3. 使用多播+单播混合:unicast_peer指定对端IP,减少多播风暴
  4. 防火墙规则:iptables限制VIP地址的ARP响应只在一台生效
  5. 监控告警:两边同时有VIP立即告警,人工介入

生产最实用的是检测网关+监控告警组合。


【面试题】8. Linux服务器如何做SSH安全加固?列出关键措施。 ​

【标准答案】 SSH加固是服务器安全的第一道防线,关键措施:

  1. 禁用root远程登录:PermitRootLogin no
  2. 禁用密码认证,只用密钥:PasswordAuthentication no,PubkeyAuthentication yes
  3. 改默认端口:Port 2222,避开自动化扫描
  4. 限制登录用户:AllowUsers deploy admin,白名单方式
  5. 设置登录超时:ClientAliveInterval 300,ClientAliveCountMax 2,5分钟无操作踢下线
  6. 禁用空密码:PermitEmptyPasswords no
  7. 限制登录尝试:MaxAuthTries 3
  8. 配置Fail2ban:多次失败自动封IP
ini
[sshd]
enabled = true
maxretry = 3
bantime = 3600
  1. 使用堡垒机:所有SSH通过堡垒机跳转,统一审计
  2. 关闭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:采集目标和实例

搭建流程:

  1. 部署Prometheus:配置prometheus.yml定义scrape_targets
yaml
scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['192.168.1.1:9100', '192.168.1.2:9100']
  1. 部署Exporter:node_exporter采集系统指标,应用暴露自定义metrics
  2. 部署Grafana:添加Prometheus数据源,导入Dashboard(如Node Exporter Full)
  3. 配置告警:Prometheus的alert_rules.yml定义规则,Alertmanager发通知
yaml
- alert: HighCPU
  expr: 100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 > 80
  for: 5m
  labels:
    severity: warning
  1. Alertmanager配置通知:支持邮件、钉钉、企业微信、Webhook

关键设计原则:Pull模式(Prometheus主动拉取)比Push更可靠,目标挂了自然拉不到;指标命名规范用namespace_subsystem_name格式;合理设置scrape_interval(默认15s)和retention时间(默认15天)。


【面试题】10. Docker容器资源限制怎么配?一个容器OOM被kill了怎么排查? ​

【标准答案】 Docker资源限制参数:

bash
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
  nginx

docker-compose写法:

yaml
services:
  app:
    mem_limit: 512m
    cpus: 1.5
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '1.5'

容器OOM排查步骤:

  1. dmesg | grep -i oom 查内核日志,确认OOM Killer触发及目标进程
  2. docker inspect <container> | grep -A5 State 看OOMKilled字段是否为true
  3. docker stats --no-stream <container> 看当前内存使用
  4. 查容器日志 docker logs <container> 看应用报错
  5. 进入容器 docker exec -it <container> sh,看进程内存占用 ps aux --sort=-%mem

常见原因:内存限制太小(Java应用JVM堆+元空间+堆外内存远超预期)、内存泄漏、缓存没做上限、JVM没设置-Xmx导致堆无限膨胀。

解决方案:调大内存限制、JVM加-Xmx -Xms -XX:MaxMetaspaceSize、修复内存泄漏代码、加监控告警(docker stats或cAdvisor)。