前端面经-nginx/docker
1.如何查看 Linux 系统负载?如何判断负载是否过高?
使用 top、htop 或 uptime 查看系统负载。
负载值(Load Average)反映 CPU 繁忙程度,理想情况下应小于 CPU 核心数。例如,4 核 CPU 的负载持续超过 4 表示过高。
2.编写一个 Shell 脚本,统计某个目录下所有 .log 文件的总行数。
#!/bin/bash
find /path/to/logs -name "*.log" -type f -exec cat {} \; | wc -l
3.如何在 Linux 中监控某个服务的端口是否正常监听?
netstat -tulpn | grep :80 # 查看80端口监听情况
ss -tulpn | grep :443 # 更高效的替代方案
curl -I http://localhost:80 # 检查HTTP服务响应
4.解释 Linux 中软链接(Symbolic Link)和硬链接(Hard Link)的区别。
软链接是一个指向原文件的路径,删除原文件后链接失效。
硬链接是原文件的另一个入口,与原文件共享 inode(索引节点),删除原文件后仍可访问。
4.1使用场景
硬链接:通常用于确保重要的文件不会因误删或重命名而丢失,尤其适合备份和保护关键数据。
软链接:更多地用于灵活的文件组织结构,例如提供程序的别名或创建易于维护的软件环境,因为它能够跟随源文件的移动和更改。
4.2创建方式
硬链接:使用 ln 命令创建,无需 -s 参数,例如:ln source_file target_link
软链接:使用 ln -s 命令创建,例如:ln -s /path/to/source_file target_link
5.如何配置 Nginx 实现负载均衡?请举例说明。
upstream web1 {# -->web1 是负载均衡组的名称,负载均衡组要定义在 server 模块之外ip_hash;# -->负载均衡算法server 192.168.1.1 weight=1 max_fails=2 fail_timeout=2;# --> 网站地址 权重为 1 最多错误几次 每次检查持续时间server 192.168.1.2 weight=1 max_fails=2 fail_timeout=2;server 127.0.0.1:8080 backup; # -->备用地址
}server {listen 80;server_name localhost;location / {proxy_pass http://webserver/;# -->反向代理,这里要改为 upstream 组名,指的是反向代理这个组中的所有元素}
}
upstream 是负载均衡模块的关键字,后面跟着的是组名,在一个组中通常会存在多台后端服务器
location 配置项会通过反向代理负载均衡组名来向后端服务器调配用户请求。
ip_hash 是负载均衡算法,按指定的算法将用户请求分发到不同的服务器中。
server 关键字后面要跟着后端服务器的地址,weight 表示权重,max_fails 表示后端服务器联系不上的次数,fail_timeout 表示检查后端服务器监控状态持续的时间。
backup一行表示,若前面 server 定义的几台后端服务器都无法工作,则使用这一台备用的后端服务器。
6.Nginx 如何处理静态文件?如何优化静态资源缓存?
6.1通过 root 或 alias 指令指定文件存储目录。
root:指定请求路径的根目录,路径为 root + location路径。
location /static/ {root /var/www/app; # 实际路径为 /var/www/app/static/
}
alias:直接映射指定路径,优先级高于 root。
location /static/ {alias /var/www/static/; # 直接映射到 /var/www/stat
6.2如何优化静态资源缓存
优化静态资源缓存的核心是通过设置合理的 HTTP 缓存头,让浏览器 / CDN 缓存资源,减少重复请求。Nginx 可通过 expires 模块或 add_header 指令实现。
- 基于 expires 模块配置缓存
作用:直接设置 Expires 和 Cache-Control 头,控制缓存时长。
配置示例:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff2)$ {# 静态资源路径匹配(正则匹配常见后缀)root /var/www/app;add_header Cache-Control "public, max-age=31536000"; # 缓存 1 年(31536000秒)expires 1y; # 等效于 Expires 头(优先于 Cache-Control max-age)access_log off; # 关闭日志减少 IOetag on; # 启用 ETag 校验(资源变化时更新缓存)
}
6.3root 和 alias 的区别?
root:请求路径会拼接在 root 后(如 location /static/ + root /var/www → /var/www/static/)。
alias:直接替换路径(如 location /static/ + alias /var/www/static/ → /var/www/static/)。
6.4如何处理静态资源更新后浏览器缓存未刷新的问题?
对资源文件名添加哈希指纹(如 app.abc123.js),变更时文件名改变,强制浏览器加载新资源。
在 HTML 中通过 /
6.5ETag 和 Last-Modified 的区别?
ETag:基于文件内容生成指纹,更精准(内容不变则指纹不变)。
Last-Modified:基于文件修改时间,可能因元数据变更(如权限修改)误判。
7.如何配置 Nginx 实现 HTTPS 访问?
7.1HTTPS 实现原理
HTTPS 通过 SSL/TLS 协议 对数据加密传输,需服务器提供 数字证书(包含公钥)和 私钥。客户端通过公钥加密请求,服务器用私钥解密,确保通信安全。
关键组件:
证书文件(.crt 或 .pem):公钥及身份信息,由 CA 机构签发。
私钥文件(.key):服务器专有,用于解密数据。
7.2配置 HTTPS 的核心步骤
7.2.1准备 SSL 证书
获取证书:
购买商业证书(如 Let’s Encrypt 免费证书、阿里云 / 腾讯云证书)。
生成自签名证书(仅用于测试,浏览器会提示风险):
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
(需按提示填写国家、域名等信息,Common Name 需与域名一致)。
证书文件位置:建议存放在 /etc/nginx/ssl/ 目录下,确保权限正确(仅 Nginx 用户可读取):
chmod 600 /etc/nginx/ssl/*.key
7.2.2 配置 Nginx 启用 HTTPS
修改 Nginx 配置文件(通常为 /etc/nginx/conf.d/default.conf 或 /etc/nginx/sites-available/default),在 server 块中添加 HTTPS 监听和证书配置:
server {listen 443 ssl; # 监听 443 端口,启用 SSLserver_name your-domain.com; # 替换为实际域名# SSL 证书与私钥路径ssl_certificate /etc/nginx/ssl/cert.pem; # 证书文件ssl_certificate_key /etc/nginx/ssl/key.pem; # 私钥文件# 以下为优化配置(可选,提升安全性和性能)ssl_protocols TLSv1.3 TLSv1.2; # 启用安全的 TLS 版本,禁用老旧协议(如 TLSv1.0/1.1)ssl_ciphers ECDHE+CHACHA20:ECDHE+AESGCM:ECDHE+ECDSA; # 推荐加密套件ssl_prefer_server_ciphers on; # 优先使用服务器端加密套件ssl_session_cache shared:SSL:10m; # 缓存会话参数,减少握手开销ssl_session_timeout 10m; # 会话缓存超时时间# 强制 HTTP 跳转 HTTPS(可选)if ($scheme = http) {return 301 https://$server_name$request_uri;}# 其他配置(如静态文件、反向代理)location / {proxy_pass http://your-backend-server; # 示例:反向代理到后端服务proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}
}
7.2.3 验证配置并重启 Nginx
检查配置语法是否正确:
nginx -t
重启 Nginx 使配置生效:
systemctl restart nginx
7.2.4 测试 HTTPS 连接
浏览器访问 https://your-domain.com,检查地址栏是否显示安全锁。
使用工具验证证书和加密配置:
SSL Labs:https://www.ssllabs.com/ssltest/(评估安全性等级)。
OpenSSL 命令:
openssl s_client -connect your-domain.com:443
7.3关键配置指令详解
7.4常见问题与优化
7.4.1 混合内容问题(Mixed Content)
现象:HTTPS 页面中引用 HTTP 资源(如图片、JS),浏览器报错并阻止加载。
确保所有资源均通过 HTTPS 引用(修改 http:// 为 https:// 或使用相对路径)。
在 Nginx 中配置 add_header Content-Security-Policy “upgrade-insecure-requests”;,强制浏览器将 HTTP 请求升级为 HTTPS。
7.4.2证书包含中间证书的情况
场景:商业证书通常由多级 CA 签发,需将中间证书与服务器证书合并为一个 .pem 文件,否则浏览器可能提示 “证书链不完整”。
操作步骤:
cat server.crt intermediate.crt > full_chain.crt # 合并证书
ssl_certificate /etc/nginx/ssl/full_chain.crt; # 配置合并后的证书路径
7.4.3.强制 HTTP 跳转 HTTPS
配置:在 HTTP 的 server 块中添加重定向规则:
server {listen 80;server_name your-domain.com;return 301 https://$server_name$request_uri; # 永久重定向到 HTTPS
}
7.4.4 性能优化:启用 OCSP Stapling
作用:减少客户端验证证书时的延迟(避免浏览器主动向 CA 发送验证请求)。
配置:
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s; # 指定 DNS 服务器解析 CA 地址
7.5面试延伸问题
7.5.1HTTPS 对性能的影响及如何优化?
影响:增加 TLS 握手延迟(约 1 个 RTT 时间)和计算开销。
优化手段:
启用会话缓存(ssl_session_cache)或会话票据(TLS Session Tickets)。
优先使用 TLSv1.3(握手延迟更低)。
部署 CDN 分担 SSL 解密压力。
7.5.2如何区分 SSL 证书和私钥的作用?
证书:包含公钥和服务器身份信息,用于客户端加密数据和验证服务器身份。
私钥:服务器专有,用于解密客户端通过公钥加密的数据,需严格保密。
7.5.3自签名证书和 CA 签发证书的区别?
自签名证书:无需 CA 认证,成本低但浏览器会提示风险,仅适用于测试环境。
CA 证书:由可信机构签发,浏览器内置根证书,用户无风险提示,适用于生产环境。
8.Nginx 日志中出现大量 502 Bad Gateway 错误,可能的原因是什么?如何排查?
可能原因:后端服务崩溃、超时、连接池耗尽、配置错误。
排查步骤:
检查后端服务状态(如 systemctl status)。
查看 Nginx 和后端服务日志。
测试后端服务端口连通性(如 telnet)。
调整 Nginx 超时参数(如 proxy_connect_timeout)。
9.Dockerfile 中 COPY 和 ADD 指令的区别是什么?
COPY:复制文件 / 目录到镜像中。
ADD:功能类似 COPY,但支持远程 URL 和自动解压压缩文件。
10.如何构建一个 Docker 镜像?如何优化镜像大小?
核心原理
Docker 镜像是由 多层只读文件系统 叠加而成,每层对应 Dockerfile 中的一条指令。构建时,Docker 按顺序执行指令并生成新的镜像层。
构建步骤
10.1编写 Dockerfile
定义镜像的基础环境、依赖安装、文件复制和启动命令。
示例 Dockerfile:
FROM python:3.9-slim # 基础镜像
WORKDIR /app # 设置工作目录
COPY requirements.txt . # 复制依赖清单
RUN pip install --no-cache-dir -r requirements.txt # 安装依赖
COPY . . # 复制应用代码
CMD ["python", "app.py"] # 启动命令
10.2创建 .dockerignore 文件
排除无需打包的文件(如 .git、日志、缓存),减少构建上下文:
.git
__pycache__
*.log
10.3执行构建命令
docker build -t myapp:1.0 . # -t:指定镜像标签,.:构建上下文路径
10.4如何减少镜像层数量?
合并 RUN 指令(如 apt-get update && install && clean)。
使用多阶段构建,避免将构建工具打包到最终镜像。
10.5镜像大小对部署的影响?
拉取速度:大镜像导致更长的部署时间。
存储成本:占用更多 registry 空间。
安全风险:包含不必要的依赖可能引入漏洞。
10.5如何实现镜像的增量更新?
使用 缓存机制:合理安排 Dockerfile 指令顺序,频繁变更的代码放在最后。
示例:先复制 requirements.txt 并安装依赖,再复制应用代码:
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt # 依赖变化时才重建此层
COPY . . # 代码变更不影响上层缓存
优化镜像大小的核心原则是:减少不必要的文件和依赖,最小化层数,分离构建与运行环境。面试时需结合具体场景(如微服务部署、CI/CD
效率)说明策略,并强调安全与性能的平衡。
11.如何实现 Docker 容器的自动重启?
# 启动时添加 --restart 参数
docker run --restart=always myapp:1.0
# 或修改已运行容器的重启策略
docker update --restart=always <container_id>
12.解释 Docker 网络模式(bridge、host、none)的区别。
bridge:默认模式,容器通过虚拟网桥与宿主机通信。
host:容器直接使用宿主机网络,无网络隔离。
none:禁用网络,容器无网络连接。
13.如何实现一个基于 GitLab CI/CD 的自动化部署流程?
在项目根目录创建 .gitlab-ci.yml。
定义 stages(如 build、test、deploy)。
使用 Docker 镜像构建应用。
部署到目标环境(如通过 SSH 执行脚本)。
示例配置:
stages:- build- deploybuild:image: docker:lateststage: buildscript:- docker build -t myapp:$CI_COMMIT_SHA .- docker push myregistry/myapp:$CI_COMMIT_SHAdeploy:image: alpine:lateststage: deployscript:- apk add openssh-client- ssh user@server "docker pull myregistry/myapp:$CI_COMMIT_SHA && docker restart myapp"
14.如何使用 Docker Compose 管理多容器应用?
作用
定义和运行 多容器应用(如 Web 服务 + 数据库 + 缓存)。
通过一个 docker-compose.yml 文件描述服务、网络、卷等资源的配置。
替代手动执行 docker run 命令,实现一键启停、扩缩容和日志查看。
核心术语
服务(Service):
基于镜像运行的容器实例(如 web 服务对应多个 web 容器副本)。
项目(Project):
由 docker-compose.yml 定义的一组关联服务的集合,默认以目录名作为项目名。
网络(Network):
服务间通信的专用网络,默认自动创建(如 项目名_default)。
卷(Volume):
持久化存储,用于容器间数据共享或数据持久化。
基础配置示例
Web 服务:基于 Node.js,监听 3000 端口,依赖 app 网络。
数据库服务:MySQL 数据库,挂载数据卷,暴露 3306 端口。
缓存服务:Redis,仅在内部网络通信。
version: '3.9' # 指定 Compose 文件版本(推荐 v3.3+)services:# 1. Web 服务web:build: . # 基于当前目录的 Dockerfile 构建镜像ports:- "3000:3000" # 映射宿主机 3000 端口到容器 3000 端口networks:- app_network # 加入名为 app_network 的网络depends_on:- db # 确保 db 服务先启动environment:- NODE_ENV=productiondeploy:replicas: 2 # 生产环境部署 2 个副本(需配合 Swarm 使用)# 2. 数据库服务db:image: mysql:8.0 # 使用官方 MySQL 镜像ports:- "3306:3306"networks:- app_networkvolumes:- db_data:/var/lib/mysql # 挂载名为 db_data 的命名卷environment:- MYSQL_ROOT_PASSWORD=secret- MYSQL_DATABASE=app_db# 3. 缓存服务redis:image: redis:alpine # 使用轻量级 alpine 版本镜像networks:- app_network# 定义网络和卷
networks:app_network: # 自定义网络,服务间通过服务名直接通信(如 web 可访问 db:3306)volumes:db_data: # 命名卷,自动创建并管理数据持久化
15.如何实现滚动更新(Rolling Update)?
# Docker Swarm 滚动更新
docker service update --image myapp:2.0 --update-parallelism 1 myapp-service# Kubernetes 滚动更新
kubectl set image deployment/myapp myapp=myapp:2.0
16.在自动化部署中,如何处理配置文件(如数据库连接信息)的安全问题?
使用环境变量传递敏感信息。
配置管理工具(如 Ansible Vault)加密配置文件。
容器编排平台(如 Kubernetes)的 Secret 机制。
CI/CD 工具的变量管理功能(如 GitLab CI/CD Variables)。
17.服务器磁盘空间满了,如何快速定位大文件 / 目录?
df -h # 查看磁盘使用情况
du -sh /* | sort -hr # 查看根目录下各目录大小
find / -type f -size +100M # 查找大于100MB的文件
18.容器无法启动,可能的原因有哪些?如何排查?
可能原因:镜像不存在、端口冲突、健康检查失败、资源不足。
排查步骤:
docker logs <container_id> 查看容器日志。
docker inspect <container_id> 检查容器配置。
docker run --entrypoint /bin/sh myimage 尝试交互式启动。
19.如何优化 Nginx 性能?
答案:
worker_processes auto; # 自动调整工作进程数
worker_connections 1024; # 每个进程的最大连接数
keepalive_timeout 65; # 长连接超时时间
gzip on; # 启用Gzip压缩
20.如何监控 Docker 容器的资源使用情况?
docker stats # 实时查看容器资源使用
ctop # 更友好的容器监控工具
21描述一次你处理生产环境故障的经历,你采取了哪些步骤?
快速恢复服务(如回滚、切换备用节点)。
收集日志和监控数据,定位问题。
分析根本原因,制定修复方案。
测试并实施修复,验证结果。
总结经验,优化流程防止复发。
22.如何设计一个高可用的微服务架构?
服务注册与发现(如 Consul、Etcd)。
负载均衡(Nginx、Traefik、Kubernetes Ingress)。
熔断与限流(Hystrix、Sentinel)。
自动化部署与自愈(Kubernetes、Docker Swarm)。
23.如何确保容器化应用的安全性?
使用最小化基础镜像(如 Distroless)。
定期更新镜像和依赖。
限制容器权限(非 root 用户、最小 Capabilities)。
网络隔离与流量控制(如 Kubernetes NetworkPolicy)。
镜像漏洞扫描(Clair、Trivy)。