Skip to content

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

【面试题】1. Nginx的upstream模块支持哪些负载均衡策略?各有什么适用场景? ​

【标准答案】 Nginx upstream支持五种主流策略:

轮询(默认):按顺序依次分配,适合后端服务器性能相近的场景,配置最简单。

权重(weight):按权重比例分配,适合服务器配置不均衡的情况。比如两台服务器,一台8核16G设weight=3,一台4核8G设weight=1,让高性能机器承担更多请求。

IP哈希(ip_hash):根据客户端IP计算哈希值分配,保证同一IP的用户始终访问同一后端服务器。适合需要会话保持但没有独立Session存储的场景,比如传统的PHP应用。

最少连接(least_conn):优先分配给当前连接数最少的服务器,适合请求处理时间差异大的场景,比如文件上传、长连接业务。

fair(第三方):根据后端服务器响应时间动态分配,响应快的多分配,适合对用户体验要求高的业务,但需要额外安装模块。

实际选型建议:一般业务用轮询或权重;有Session保持需求用ip_hash;长连接或请求耗时差异大用least_conn;追求极致响应速度可以考虑fair。

【面试题】2. 生产环境Nginx出现502 Bad Gateway错误,如何系统化排查? ​

【标准答案】 502错误本质是Nginx作为代理时,无法从上游服务器获取有效响应。按这个思路排查:

第一步看上游服务状态:检查后端服务是否存活,端口是否监听。用netstat -tlnp | grep 端口或ss -tlnp确认。服务挂了就重启。

第二步检查Nginx配置:确认proxy_pass地址是否正确,upstream的后端地址和端口是否匹配。常见错误是配置写成了内网IP但服务只绑定了127.0.0.1。

第三步看防火墙和SELinux:Nginx服务器能否连通后端服务器端口?用telnet 后端IP 端口或nc -zv 后端IP 端口测试连通性。防火墙拦截或SELinux策略拒绝都会导致502。

第四步检查后端服务日志:服务活着但不响应?看应用日志有没有报错,数据库连接池是否耗尽,是否在Full GC卡死。

第五步看Nginx错误日志:/var/log/nginx/error.log里会有更详细的错误信息,比如connect() failed (111: Connection refused)说明连接被拒绝,upstream timed out说明后端响应超时。

第六步检查资源瓶颈:后端服务器CPU、内存、文件描述符是否耗尽?用top、free -m、ulimit -n确认。

总结:502排查核心是确认"上游服务是否存活、Nginx能否连通上游、上游是否正常响应"这三个环节。

【面试题】3. Nginx的location匹配规则是什么?优先级如何确定? ​

【标准答案】 location匹配有四种类型,优先级从高到低:

精确匹配(=):location = /exact/path,完全匹配才命中,优先级最高。适合静态资源或特定接口的精准路由。

前缀匹配优先匹配(^~):location ^~ /static/,匹配后停止搜索正则,优先级次之。适合静态资源目录,避免被后面的正则规则覆盖。

正则匹配(~ 和 ~*):location ~ \.php$区分大小写,location ~* \.(jpg|png)$不区分大小写。正则按配置文件中的出现顺序匹配,先写的先匹配。

普通前缀匹配:location /api/,没有修饰符的普通匹配,优先级最低。如果同时匹配多个,选最长前缀的那个。

实际例子: 请求/static/logo.png,同时匹配location /static/和location ~* \.png$,但因为^~优先级高于正则,会走^~规则。

配置建议:

  • 精确匹配用于首页或关键接口
  • ^~用于静态资源目录
  • 正则用于扩展名匹配或复杂路由
  • 普通前缀用于API网关或代理转发

【面试题】4. Tomcat的Connector支持哪些线程模型?生产环境如何选择? ​

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

BIO(阻塞IO,已废弃):每个请求一个线程,线程阻塞等待请求处理完成。Tomcat 8.5后已移除,不推荐使用。

NIO(非阻塞IO):基于Java NIO实现,用少量线程处理大量连接。适合连接数多但请求处理快的场景,是Tomcat 8/9的默认选择。配置protocol="org.apache.coyote.http11.Http11NioProtocol"。

APR(Apache Portable Runtime):通过JNI调用本地库,性能最优。需要安装APR库和Tomcat Native,适合对性能要求极高的生产环境。配置protocol="org.apache.coyote.http11.Http11AprProtocol"。

NIO2:Tomcat 8引入,基于Java 7的异步IO,性能介于NIO和APR之间。

选型建议:

  • 中小规模应用:NIO足够,开箱即用无需额外依赖
  • 高并发、低延迟场景:APR,但需要运维安装本地库
  • 容器化环境:优先NIO,避免容器内安装本地库的复杂性

调优参数:

  • maxThreads:最大工作线程数,默认200
  • acceptCount:等待队列长度,默认100
  • maxConnections:最大连接数,NIO默认10000

【面试题】5. Linux服务器出现高负载(load average很高),如何定位原因? ​

【标准答案】 load average反映系统运行队列长度,高负载需要区分是CPU密集还是IO密集。

第一步确认负载类型: 用top或uptime看load average,再用top里的%Cpu(s)行判断:

  • us高:用户态CPU占用高,应用代码或计算密集
  • sy高:内核态CPU占用高,系统调用频繁
  • wa高:IO等待高,磁盘或网络IO瓶颈
  • id高:空闲CPU多但load高 → 进程在等待IO,不是CPU瓶颈

第二步定位具体进程: 用top -c看具体进程的CPU占用,top后按P按CPU排序,按M按内存排序。找到占用的进程后,用strace -p 进程ID跟踪系统调用。

第三步IO问题深入排查: 如果是wa高,用iostat -x 1看磁盘IO,关注%util和await。用iotop找出占用IO最多的进程。

第四步检查内存和交换: 用free -m看内存,vmstat 1看swap切换。频繁swap会导致load高但CPU不高。

第五步检查进程状态: 用ps aux | awk '$8 ~ /D/ {print}'找出D状态(不可中断睡眠)的进程,通常在等待IO。

典型场景:

  • Java应用CPU高:jstack抓线程栈定位热点代码
  • 数据库IO高:检查慢查询、索引、是否全表扫描
  • 磁盘满导致IO异常:df -h确认空间

【面试题】6. 如何配置Nginx实现动静分离?有什么优势? ​

【标准答案】 动静分离是指静态资源(CSS、JS、图片)由Nginx直接处理,动态请求转发给后端应用服务器。

典型配置:

nginx
server {
    listen 80;
    server_name example.com;
    
    # 静态资源
    location ~* \.(css|js|jpg|png|gif|ico|woff|woff2)$ {
        root /var/www/static;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    # 动态请求转发
    location / {
        proxy_pass http://backend_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

upstream backend_servers {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

核心优势:

  1. 性能提升:Nginx处理静态文件效率远高于Tomcat/Java应用,Nginx用C写的事件驱动架构,Tomcat需要经过Servlet容器层
  2. 减轻后端压力:静态请求不经过应用服务器,释放应用服务器资源处理业务逻辑
  3. 便于CDN加速:静态资源独立部署,可推送至CDN边缘节点
  4. 浏览器缓存:静态资源可设置长期缓存(expires),减少重复请求
  5. 独立扩展:静态资源服务器和应用服务器可独立扩容

生产建议:

  • 静态资源使用独立域名(如static.example.com)
  • 配置gzip压缩减少传输体积
  • 开启etag支持增量更新
  • 使用HTTP/2多路复用

【面试题】7. 生产环境如何防止SSH暴力破解? ​

【标准答案】 SSH暴力破解是最常见的攻击方式,需要多层防护:

第一层:修改默认端口 修改/etc/ssh/sshd_config的Port 22为非常用端口(如2222),可规避大量自动扫描脚本。注意同时修改防火墙规则。

第二层:禁止密码登录,强制密钥认证

bash
# 修改sshd_config
PasswordAuthentication no
PubkeyAuthentication yes

密钥认证比密码安全得多,攻击者无法暴力破解私钥。

第三层:限制登录用户

bash
AllowUsers user1@192.168.1.0/24 user2
# 或限制用户组
AllowGroups ssh-users

只允许特定用户或IP段登录。

第四层:安装Fail2ban 自动监控日志,多次失败后封禁IP。配置/etc/fail2ban/jail.local:

ini
[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 3600

3次失败封禁1小时。

第五层:配置防火墙白名单

bash
# iptables只允许特定IP
iptables -A INPUT -p tcp --dport 2222 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 2222 -j DROP

第六层:启用双因素认证 安装libpam-google-authenticator,登录时需要手机验证码。

第七层:日志监控 用lastb查看失败登录,/var/log/secure分析攻击来源,配合告警系统。

【面试题】8. Prometheus+Grafana监控体系如何搭建?核心概念是什么? ​

【标准答案】 Prometheus+Grafana是云原生时代最流行的监控方案。

核心概念:

  • Metric(指标):带标签的时间序列数据,如http_requests_total{method="GET", status="200"}
  • Label(标签):指标的维度标识,用于聚合和过滤
  • Target(目标):被监控的服务端点,暴露/metrics接口
  • Job(任务):一组相同功能的Target集合
  • Exporter(导出器):将第三方系统指标转换为Prometheus格式的组件

架构流程:

  1. 应用或Exporter暴露/metrics接口
  2. Prometheus Server按配置周期拉取(Pull模式)
  3. 数据存入时序数据库(TSDB)
  4. PromQL查询语言分析数据
  5. Grafana可视化展示,配置告警

搭建步骤:

yaml
# prometheus.yml配置
scrape_configs:
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['192.168.1.10:9100', '192.168.1.11:9100']
  
  - job_name: 'myapp'
    static_configs:
      - targets: ['192.168.1.20:8080']

常用Exporter:

  • node_exporter:主机监控(CPU、内存、磁盘)
  • mysqld_exporter:MySQL监控
  • nginx-vts-exporter:Nginx监控
  • jmx_exporter:Java应用JMX监控

Grafana配置:

  • 添加Prometheus数据源
  • 导入社区Dashboard(如Node Exporter Full)
  • 自定义Panel可视化
  • 配置告警规则和通知渠道

优势:

  • Pull模式,服务端不需要主动推送
  • 多维度标签,灵活聚合
  • PromQL强大查询能力
  • 生态丰富,几乎所有组件都有Exporter

【面试题】9. Docker容器的资源限制如何配置?为什么要限制? ​

【标准答案】 容器不限制资源会相互争抢,甚至拖垮宿主机。

CPU限制:

bash
# 限制CPU使用率(相对于单核的比例)
docker run --cpus=1.5 nginx  # 最多使用1.5核

# 指定CPU核心
docker run --cpuset-cpus=0,1 nginx  # 只用第0和第1核

# CPU权重(相对值,默认1024)
docker run --cpu-shares=512 nginx  # CPU争抢时权重是默认的一半

内存限制:

bash
# 内存硬限制
docker run --memory=2g nginx  # 最多2GB内存

# 内存+交换限制
docker run --memory=2g --memory-swap=2g nginx  # 不允许用swap

# 内存软限制(内存充足时可用更多)
docker run --memory=2g --memory-reservation=1g nginx

IO限制(需要Linux内核支持):

bash
# 限制磁盘IO
docker run --device-read-bps=/dev/sda:10mb nginx  # 读速度限制
docker run --device-write-iops=/dev/sda:100 nginx  # 写IO次数限制

为什么要限制:

  1. 防止资源耗尽:单个容器吃满资源不影响其他容器
  2. 性能隔离:避免"吵闹邻居"问题
  3. 成本控制:按资源配额计费的云环境控制成本
  4. 稳定性保障:内存溢出时容器被杀而不是拖垮宿主机
  5. 公平调度:多个容器竞争资源时按权重分配

docker-compose配置:

yaml
services:
  app:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 1G

生产建议:

  • 所有容器都必须设置资源限制
  • 先压测确定合理值,再应用到生产
  • 配置监控告警,资源接近限制时预警

【面试题】10. LVS负载均衡有哪些模式?各自的优缺点是什么? ​

【标准答案】 LVS(Linux Virtual Server)是内核级负载均衡,有三种工作模式:

NAT模式(Network Address Translation): 请求和响应都经过Director Server,Director修改目标IP转发给Real Server,响应再由Director修改源IP返回客户端。

优点:Real Server可以是任意OS,无需特殊配置 缺点:Director是性能瓶颈,所有流量都经过它 适用:小型集群,流量不大

DR模式(Direct Routing): Director只处理请求,响应由Real Server直接返回客户端。Director修改目标MAC地址转发,Real Server需要配置VIP在本地回环接口。

优点:响应不经过Director,性能最优,可支撑极高并发 缺点:Director和Real Server必须在同一网段,Real Server需要绑定VIP并配置ARP抑制 适用:大型高并发场景,最常用模式

TUN模式(IP Tunneling): Director将请求封装在IP隧道中发送给Real Server,Real Server解包处理并直接响应客户端。

优点:支持跨网段部署,可异地灾备 缺点:Real Server需要支持IP隧道协议,配置复杂 适用:异地多活、跨机房部署

对比总结:

模式性能网络要求配置复杂度
NAT低无限制简单
DR高同网段中等
TUN高可跨网段复杂

生产选型:

  • 流量适中、追求简单:NAT模式
  • 高并发、追求性能:DR模式(主流选择)
  • 异地灾备、跨机房:TUN模式

DR模式配置关键点:

  • 所有Real Server绑定VIP到lo接口
  • 配置arp_ignore=1和arp_announce=2抑制ARP响应