本轮 服务器运维面试题库(带答案)
【面试题】1. 请解释 Nginx 的 location 匹配优先级规则,并举例说明精确匹配和正则匹配的区别。
【标准答案】 Nginx 的 location 匹配有四种类型,优先级从高到低:
- 精确匹配
=— 最高优先级,完全匹配时立即停止搜索 - 前缀匹配
^~— 匹配后停止正则搜索 - 正则匹配
~或~*— 区分大小写和不区分大小写的正则 - 普通前缀匹配 — 无修饰符,优先级最低
举例说明:
location = /api/user {
# 精确匹配,只匹配 /api/user
proxy_pass http://backend;
}
location ~ ^/static/.*\.(jpg|png)$ {
# 正则匹配,匹配 /static/ 下的 jpg/png 文件
expires 30d;
}
location /api/ {
# 普通前缀匹配,匹配所有 /api/ 开头的请求
proxy_pass http://backend;
}关键点:精确匹配用 = 适合单一固定路径;正则匹配用 ~ 适合模式匹配场景。面试时强调实际配置经验,比如用 = 匹配健康检查接口 /health,用 ~ 匹配静态资源缓存规则。
【面试题】2. Tomcat 出现 OOM(内存溢出)时,你如何排查和解决?请详细说明排查步骤。
【标准答案】 OOM 排查分三步走:
第一步:定位问题类型
java.lang.OutOfMemoryError: Java heap space→ 堆内存不足java.lang.OutOfMemoryError: PermGen space/Metaspace→ 类加载过多(JDK8+ 是 Metaspace)java.lang.OutOfMemoryError: GC overhead limit exceeded→ GC 效率过低
第二步:获取现场证据
# 查看 Tomcat 进程 PID
ps -ef | grep tomcat
# 生成 heap dump(OOM 时自动生成,需配置)
jmap -dump:format=b,file=heap.hprof <pid>
# 查看堆内存使用情况
jmap -heap <pid>
# 查看 GC 情况
jstat -gcutil <pid> 1000 10第三步:分析与解决
- 用 MAT(Memory Analyzer Tool)或 JProfiler 分析 hprof 文件
- 找出占用内存最大的对象,定位内存泄漏点
- 检查代码中是否有未关闭的连接、集合无限增长、大对象未释放等
优化方案:
- 调整 JVM 参数:
-Xms2g -Xmx4g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m - 添加 OOM 自动导出:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof - 优化代码,修复内存泄漏
面试时强调:生产环境必须配置 HeapDumpOnOutOfMemoryError,出问题才有证据可查。
【面试题】3. Nginx 配置了负载均衡后,后端服务器健康检查如何实现?请对比主动检查和被动检查的优劣。
【标准答案】 Nginx 健康检查有两种方式:
被动检查(原生支持)
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}max_fails:失败次数阈值fail_timeout:标记为不可用的时间窗口
原理:Nginx 在代理请求时,如果后端返回错误或超时,记录失败次数;达到阈值后,暂时剔除该服务器。
主动检查(需 nginx_plus 或第三方模块)
# 商业版 Nginx Plus
upstream backend {
zone backend 64k;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
health_check interval=5s uri=/health;
}对比:
| 维度 | 被动检查 | 主动检查 |
|---|---|---|
| 实现复杂度 | 低(原生) | 高(需商业版或模块) |
| 发现故障速度 | 慢(需真实流量触发) | 快(主动探测) |
| 资源消耗 | 无额外消耗 | 有定时探测开销 |
| 适用场景 | 请求量稳定的服务 | 对可用性要求极高的服务 |
我的实践经验:中小规模项目用被动检查即可,配合 proxy_connect_timeout 和 proxy_read_timeout 控制超时;大规模高可用场景推荐 Nginx Plus 或用 HAProxy 替代,它的主动健康检查更强大。
【面试题】4. Linux 服务器负载突然飙高(load average > CPU 核心数),你如何快速定位瓶颈?
【标准答案】 高负载排查四步法:
第一步:确认负载类型
# 查看 load average 和 CPU 核心
top # 按 1 展开各核心
uptime # 快速看 load average
# 判断:load average > CPU 核心数 = 系统过载第二步:定位资源瓶颈
# CPU 密集型:us% + sy% 很高
top -c # 查看具体进程命令
# I/O 密集型:wa%(iowait)很高
iostat -x 1 10 # 查看磁盘 IO
# 内存不足:频繁 swap
free -h
vmstat 1 10 # 看 si/so(swap in/out)第三步:找出罪魁祸首
# CPU 占用最高的进程
top -c
ps aux --sort=-%cpu | head -20
# I/O 占用最高的进程
iotop -oP # 需安装 iotop
# 网络连接异常
netstat -antp | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn
ss -s # 快速统计连接状态第四步:紧急处理
# CPU 飙高:如果是异常进程,直接杀掉
kill -9 <pid>
# I/O 飙高:检查磁盘空间、慢查询日志
df -h
# MySQL 慢查询日志,Nginx access log 异常增长等
# 内存不足:重启占用过高的服务,或临时扩容 swap
dd if=/dev/zero of=/swapfile bs=1G count=4
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile面试加分点:我会用 atop 或 sar 持续监控,提前发现趋势;dmesg | tail 检查是否有 OOM killer 或硬件错误。高负载往往是多个因素叠加,需要系统化排查。
【面试题】5. 如何配置 Nginx 实现 HTTPS 双向认证?什么场景需要双向认证?
【标准答案】 HTTPS 双向认证:不仅客户端验证服务器证书,服务器也验证客户端证书。
适用场景:
- 企业内部 API 对接,只允许授权客户端访问
- 金融/支付系统,要求客户端身份强认证
- 物联网设备与服务器通信
配置步骤:
server {
listen 443 ssl;
server_name api.example.com;
# 服务器证书(客户端验证服务器)
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# 客户端证书验证(服务器验证客户端)
ssl_client_certificate /etc/nginx/ssl/ca.crt; # CA 证书
ssl_verify_client on; # 强制客户端认证
ssl_verify_depth 2;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://backend;
}
}客户端证书生成流程:
# 1. 生成客户端私钥和 CSR
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
# 2. 用 CA 签发客户端证书
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt -days 365
# 3. 打包为 PKCS#12 格式(供浏览器导入)
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key \
-out client.p12测试:
curl --cert client.crt --key client.key https://api.example.com面试时强调:双向认证成本高,需要为每个客户端签发和管理证书,通常配合证书撤销列表(CRL)或 OCSP 使用,适合安全要求极高的场景。
【面试题】6. 请解释 Keepalived + Nginx 高可用方案的原理,并说明如何避免脑裂问题。
【标准答案】 Keepalived 原理:
- 基于 VRRP(虚拟路由冗余协议)实现 IP 漂移
- 两台 Nginx 服务器配置主备角色,共享虚拟 IP(VIP)
- 主节点故障时,VIP 自动漂移到备节点,实现秒级切换
架构示意:
VIP: 192.168.1.100
|
+----------------+----------------+
| |
Master (Keepalived) Backup (Keepalived)
192.168.1.10 (Nginx) 192.168.1.11 (Nginx)Keepalived 配置示例(主节点):
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.1.100
}
# 监控 Nginx 进程
track_script {
check_nginx
}
}Nginx 健康检查脚本:
#!/bin/bash
# /etc/keepalived/check_nginx.sh
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
systemctl start nginx
sleep 2
if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then
systemctl stop keepalived
fi
fi脑裂问题及解决方案:
脑裂现象:主备都认为自己是主,同时持有 VIP,导致流量混乱或数据不一致。
原因:
- 网络分区(防火墙阻断 VRRP 组播)
- Keepalived 进程异常但未退出
- 服务器负载过高导致心跳超时
解决方案:
- 多播地址配置正确:确保 VRRP 组播包能互通
- 降低优先级逻辑:Nginx 异常时自动降低优先级,而不是直接停止 Keepalived
- 增加仲裁机制:引入第三方节点或服务做仲裁
- 监控告警:监控 VIP 冲突、Keepalived 状态异常
- 日志审计:定期检查
/var/log/messages中的 VRRP 状态切换记录
# 检测脑裂脚本(在备节点运行)
#!/bin/bash
VIP=192.168.1.100
MASTER_IP=192.168.1.10
# 如果能 ping 通主节点,但本机也有 VIP,说明脑裂
if ping -c 1 $MASTER_IP &> /dev/null; then
if ip addr show | grep -q $VIP; then
echo "脑裂告警!主备同时持有 VIP"
# 发送告警,可选择关闭本机 VIP
fi
fi面试加分点:生产环境建议 Keepalived + Nginx + 监控 三位一体,配合脚本实现 Nginx 故障自动重启、Keepalived 状态监控、VIP 冲突检测。
【面试题】7. Tomcat Connector 有哪几种线程模型?NIO 和 APR 有什么区别?生产环境如何选择?
【标准答案】 Tomcat Connector 有三种线程模型:
1. BIO(Blocking I/O,阻塞式)
- Tomcat 8.5 之前的默认模型
- 每个请求占用一个线程,线程阻塞等待请求
- 缺点:并发能力差,线程资源消耗大
- 适用:低并发场景,已逐渐淘汰
2. NIO(Non-blocking I/O,非阻塞式)
- Tomcat 8.5+ 的默认模型
- 基于 Java NIO API,使用少量线程处理大量连接
- 优点:高并发、资源利用率高
- 适用:高并发、连接数多但请求处理时间长的场景
3. APR(Apache Portable Runtime)
- 使用本地库(C 语言实现),性能最优
- 需要 Tomcat Native 库支持
- 优点:性能接近 Nginx,SSL 性能优秀
- 适用:对性能要求极高、大规模生产环境
配置方式(server.xml):
<!-- NIO(默认) -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200" minSpareThreads="25" acceptCount="100" />
<!-- APR(需安装 Tomcat Native) -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="200" />NIO vs APR 对比:
| 维度 | NIO | APR |
|---|---|---|
| 实现方式 | Java API | C 本地库 |
| 性能 | 优秀 | 最优(提升 10-20%) |
| SSL 性能 | 一般 | 优秀(OpenSSL 加速) |
| 部署复杂度 | 低(开箱即用) | 高(需编译安装 Native) |
| 稳定性 | 高(纯 Java) | 依赖系统库,需版本匹配 |
| 跨平台 | 完全跨平台 | 依赖系统,需单独编译 |
生产环境选择建议:
- 常规项目:NIO 足够,默认配置即可,无需额外折腾
- 高并发/SSL 密集:APR,但需要运维团队有能力编译和维护 Tomcat Native
- Spring Boot 内嵌 Tomcat:默认 NIO,可通过配置切换 APR(需添加依赖)
我的实践经验:90% 的项目用 NIO 即可;APR 的性能提升有限,但部署和维护成本高,只有在性能成为明确瓶颈时才考虑。SSL 性能优化更推荐用 Nginx 做卸载,而非在 Tomcat 层折腾 APR。
【面试题】8. 如何用 ELK Stack(Elasticsearch + Logstash + Kibana)搭建服务器日志监控系统?请简述架构和数据流。
【标准答案】 ELK Stack 架构:
应用服务器 → Filebeat → Logstash → Elasticsearch → Kibana
↓
Kafka(可选,缓冲层)组件职责:
- Filebeat:轻量级日志采集器,部署在应用服务器,实时收集日志
- Logstash:数据处理管道,解析、过滤、转换日志格式
- Elasticsearch:分布式搜索引擎,存储和索引日志
- Kibana:可视化平台,日志查询、仪表盘、告警
部署步骤:
1. 安装 Elasticsearch(数据存储)
# docker-compose.yml
services:
elasticsearch:
image: elasticsearch:8.12.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- "9200:9200"
volumes:
- es_data:/usr/share/elasticsearch/data2. 安装 Logstash(数据处理)
# /etc/logstash/conf.d/nginx.conf
input {
beats {
port => 5044
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "nginx-%{+YYYY.MM.dd}"
}
}3. 安装 Kibana(可视化)
kibana:
image: kibana:8.12.0
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
ports:
- "5601:5601"4. 安装 Filebeat(日志采集)
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
fields:
app: nginx
fields_under_root: true
output.logstash:
hosts: ["logstash:5044"]高可用架构:
- Elasticsearch 集群(至少 3 节点)
- Kafka 作为缓冲层,防止日志高峰时 Logstash 崩溃
- Logstash 多实例负载均衡
典型查询场景:
- 统计 5xx 错误趋势:Kibana 可视化面板
- 慢请求分析:响应时间 > 1s 的请求
- 异常 IP 追踪:某个 IP 的访问频率、请求路径
- 业务指标监控:API 调用成功率、响应时间分布
面试加分点:
- 提到 Elasticsearch 生命周期管理(ILM),自动删除或归档旧日志
- 提到 Filebeat vs Fluentd 的选择:Filebeat 更轻量,Fluentd 功能更丰富
- 提到 Kibana 告警:可配置 Watcher 或集成 Prometheus Alertmanager
【面试题】9. Linux 服务器的 iptables 和 firewalld 有什么区别?生产环境应该用哪个?请举例配置 Web 服务器防火墙规则。
【标准答案】 iptables vs firewalld 对比:
| 维度 | iptables | firewalld |
|---|---|---|
| 架构 | 规则链,需手动管理顺序 | 区域(Zone)概念,策略化管理 |
| 配置方式 | 命令行规则,重启失效 | XML 配置文件,支持运行时/永久分离 |
| 动态更新 | 需重启服务或重载规则 | 支持运行时修改,无中断 |
| 学习曲线 | 复杂,需理解链和表 | 相对简单,区域概念直观 |
| 适用系统 | CentOS 6 及以下 | CentOS 7+、RHEL 7+、Fedora |
| 底层 | netfilter | 底层仍是 iptables(nftables) |
生产环境选择:
- CentOS 7+ 默认 firewalld,建议使用 firewalld
- 老系统或习惯 iptables,可继续使用
- 大规模自动化部署,firewalld 更易管理
firewalld 配置 Web 服务器示例:
# 查看默认区域
firewall-cmd --get-default-zone
# public
# 开放 HTTP/HTTPS
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 开放自定义端口(如 8080)
firewall-cmd --permanent --add-port=8080/tcp
# 允许特定 IP 访问 SSH
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
# 拒绝特定 IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.100" reject'
# 开启端口转发(将 8080 转发到 80)
firewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toport=80
# 重载配置
firewall-cmd --reload
# 查看当前规则
firewall-cmd --list-alliptables 配置示例(等价规则):
# 清空规则
iptables -F
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 开放 HTTP/HTTPS
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 22 -s 192.168.1.0/24 -j ACCEPT
# 拒绝其他入站
iptables -A INPUT -j DROP
# 保存规则
service iptables save # CentOS 6
iptables-save > /etc/sysconfig/iptables面试加分点:
- 提到 ufw(Ubuntu):
ufw allow 80/tcp,更简单 - 提到 安全加固:默认拒绝所有入站,只开放必要端口,SSH 改用非标准端口
- 提到 Fail2ban:自动封禁暴力破解 IP,与 iptables/firewalld 联动
我的经验:现代 Linux 发行版建议用 firewalld 或 nftables(iptables 的继任者),配置更清晰,动态管理更方便。关键是默认拒绝策略 + 最小权限原则。
【面试题】10. 请设计一个 LVS + Keepalived + Nginx 的高可用负载均衡架构,并说明各组件的作用和故障切换流程。
【标准答案】 架构设计:
用户请求
|
VIP: 192.168.1.100
|
+--------------+--------------+
| |
LVS Master (Keepalived) LVS Backup (Keepalived)
192.168.1.10 192.168.1.11
| |
+--------+---------+----------+
|
+------------+------------+------------+
| | | |
Nginx 1 Nginx 2 Nginx 3 Nginx N
RS1 RS2 RS3 RS N组件职责:
LVS(Linux Virtual Server)
- 四层负载均衡(基于 IP + 端口)
- DR 模式:请求经过 LVS,响应直接返回客户端(性能最优)
- NAT 模式:请求和响应都经过 LVS(简单但性能受限)
- 作用:高性能流量分发,支持十万级并发
Keepalived
- 实现 LVS 主备高可用
- VRRP 协议保证 VIP 漂移
- 健康检查:监控后端 Nginx 服务器状态
- 作用:故障自动切换,秒级恢复
Nginx
- 七层负载均衡(基于 HTTP 头、URL)
- 反向代理、SSL 卸载、缓存
- 作用:业务层流量调度、SSL 处理、静态资源服务
为什么需要 LVS + Nginx 两层?
- LVS:四层,性能极高,但功能单一
- Nginx:七层,功能丰富,但性能低于 LVS
- 组合使用:LVS 承接海量连接 → Nginx 做智能分发和业务处理
配置示例:
Keepalived + LVS(主节点):
# /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_MASTER
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.1.100
}
}
# LVS 配置
virtual_server 192.168.1.100 80 {
delay_loop 6
lb_algo rr # 轮询
lb_kind DR # DR 模式
persistence_timeout 0
protocol TCP
# 后端 Nginx 服务器
real_server 192.168.1.20 80 {
weight 1
TCP_CHECK {
connect_timeout 3
connect_port 80
}
}
real_server 192.168.1.21 80 {
weight 1
TCP_CHECK {
connect_timeout 3
connect_port 80
}
}
}后端 Nginx 配置(Real Server):
# DR 模式需要在后端服务器配置 VIP(不响应 ARP)
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
# 在 lo 接口绑定 VIP
ip addr add 192.168.1.100/32 dev lo故障切换流程:
LVS Master 故障
- Keepalived 检测到 Master 失效
- Backup 接管 VIP,成为新 Master
- 切换时间:1-3 秒(advert_int 决定)
后端 Nginx 故障
- Keepalived 的 TCP_CHECK 检测到 Nginx 端口不可达
- 自动从 LVS 调度列表中移除该节点
- 恢复后自动加回
Nginx 进程崩溃
- Nginx 内置 master-worker 机制自动重启 worker
- 如果 master 崩溃,用 systemd 或 supervisor 自动拉起
面试加分点:
- 提到 健康检查策略:TCP_CHECK(端口检查)、HTTP_GET(HTTP 健康检查)、SSL_GET(HTTPS)
- 提到 会话保持:
persistence_timeout参数,或用 IP Hash - 提到 监控告警:Prometheus 监控 LVS 连接数、Keepalived 状态、Nginx 请求数
- 提到 容量规划:LVS 可支持百万级并发,Nginx 单机 5-10 万 QPS
我的实践经验:
- 小规模场景:单 Nginx + Keepalived 足够
- 中大规模:LVS + Keepalived + 多 Nginx
- 超大规模:引入 DNS 轮询、CDN、多机房部署
- 关键是监控和告警,出问题第一时间知道,而不是等用户反馈