news 2026/7/12 4:29:34

Linux下Docker Compose里运行Nginx故障诊断Shell脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux下Docker Compose里运行Nginx故障诊断Shell脚本
#!/bin/bash# ==============================================================================# Nginx on Docker Compose 故障系统化诊断脚本# 融哲于技:本体论、奥卡姆剃刀、辩证法、实用主义、道家无为、整体论# ==============================================================================# 功能:针对 Docker Compose 管理的 Nginx 服务意外中断进行系统化取证与诊断# 使用:./nginx_diagnose.sh [容器名或服务名,默认尝试自动探测]# 要求:在 docker-compose.yml 所在目录或通过环境变量指定,安装 docker 与 jq(可选)set-opipefail# --- 颜色定义 ---RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'# No Color# --- 参数/变量 ---TARGET=${1:-nginx}# 目标服务名或容器名COMPOSE_CMD="docker compose"# 优先使用 Docker Compose v2CONTAINER_ID=""EXIT_CODE=""OOM_KILLED=""# 实用主义:检查 docker 命令是否存在,如不存在则提示并退出if!command-vdocker&>/dev/null;thenecho-e"${RED}[错误] 未找到 docker 命令,请确认 Docker 已安装。${NC}"exit1fi# 确定 docker compose 命令可用形式(奥卡姆剃刀:用最简方式)if!dockercompose version&>/dev/null;thenifcommand-vdocker-compose&>/dev/null;thenCOMPOSE_CMD="docker-compose"elseecho-e"${YELLOW}[警告] 未检测到 docker compose,将跳过 compose 相关操作。${NC}"COMPOSE_CMD=""fifiecho-e"${BLUE}========== Nginx 故障诊断开始(目标:${TARGET})==========${NC}"# ======================================================================# 步骤1:本体论定性 —— 界定“实体”的存在性与状态# 哲学依据:本体论追问“何物存在”。只有先确定容器这一实体的本质状态# (不存在/Exited/Running 但无响应),才能锁定正确的排查方向。# ======================================================================echo-e"\n${GREEN}[步骤1] 本体论定性:确认容器存在与状态${NC}"# 尝试通过 docker compose 获取容器 ID(若服务名准确)if[-n"$COMPOSE_CMD"];thenCONTAINER_ID=$($COMPOSE_CMDps-q"$TARGET"2>/dev/null)fi# 如果未获取到,尝试直接通过名称查找容器(本体论:实体可能独立于 compose)if[-z"$CONTAINER_ID"];thenCONTAINER_ID=$(dockerps-a--filter"name=${TARGET}"--format"{{.ID}}"|head-1)fiif[-z"$CONTAINER_ID"];thenecho-e"${RED}[本体论判定] 实体不存在:未找到名称包含 '${TARGET}' 的容器。${NC}"echo-e"${YELLOW}手工检验步骤:请确认服务名是否正确,尝试 'docker ps -a' 查看所有容器。${NC}"exit1fi# 获取容器状态(用于本体论区分)CONTAINER_STATE=$(dockerinspect--format='{{.State.Status}}'"$CONTAINER_ID"2>/dev/null)echo-e"容器 ID:${CONTAINER_ID}"echo-e"容器状态:${CONTAINER_STATE}"case"$CONTAINER_STATE"inrunning)echo-e"${YELLOW}[本体论判定] 实体存续但可能存在功能异常(服务不可用)。${NC}"echo-e"${YELLOW}手工检验步骤:检查容器内 Nginx 进程是否正常监听端口:${NC}"echo" docker exec${CONTAINER_ID}netstat -tulpn | grep nginx"echo-e"${YELLOW}检查健康检查日志/状态:docker inspect${CONTAINER_ID}| jq .[0].State.Health${NC}";;exited)echo-e"${RED}[本体论判定] 实体已终止(Exited),进程生命周期结束,需排查死亡原因。${NC}";;*)echo-e"${RED}[本体论判定] 实体状态异常:${CONTAINER_STATE}${NC}";;esac# ======================================================================# 步骤2:实用主义快速取证 + 辩证法权衡(保留现场 vs 快速恢复)# 哲学依据:实用主义主张最小可行操作获取最大效果。# 辩证法承认“恢复业务”与“深挖根因”的矛盾,抓大放小——先花30秒取证。# ======================================================================echo-e"\n${GREEN}[步骤2] 实用主义快速取证(瞬时证据收集)${NC}"# 无论容器是否退出,我们都收集一些不会消失的瞬时信息echo-e"${BLUE}2.1 检查容器 OOMKilled 标记与退出码${NC}"INSPECT_OUT=$(dockerinspect"$CONTAINER_ID"2>/dev/null)OOM_KILLED=$(echo"$INSPECT_OUT"|jq-r'.[0].State.OOMKilled'2>/dev/null)EXIT_CODE=$(echo"$INSPECT_OUT"|jq-r'.[0].State.ExitCode'2>/dev/null)if["$OOM_KILLED"=="null"]||[-z"$OOM_KILLED"];then# jq 不可用时的回退(奥卡姆剃刀:最简方法)OOM_KILLED=$(dockerinspect--format='{{.State.OOMKilled}}'"$CONTAINER_ID"2>/dev/null)EXIT_CODE=$(dockerinspect--format='{{.State.ExitCode}}'"$CONTAINER_ID"2>/dev/null)fiecho" OOMKilled:$OOM_KILLED"echo" ExitCode :$EXIT_CODE"echo-e"\n${BLUE}2.2 收集最近的容器日志(最后50行)${NC}"if[-n"$COMPOSE_CMD"];then$COMPOSE_CMDlogs--tail=50"$TARGET"2>/dev/null||\dockerlogs--tail=50"$CONTAINER_ID"2>/dev/nullelsedockerlogs--tail=50"$CONTAINER_ID"2>/dev/nullfiecho-e"\n${BLUE}2.3 收集系统内核日志尾部(dmesg,关联 OOM 等)${NC}"dmesg-T|tail-302>/dev/null||dmesg|tail-30# 辩证法:此时我们已握有关键证据,是否立即重启以恢复服务?if["$CONTAINER_STATE"=="exited"];thenecho-e"\n${YELLOW}[辩证法权衡] 容器已停止,已收集关键瞬时数据。${NC}"echo-e"${YELLOW}手工决策:是否现在就重启服务?(重启可快速恢复业务,但可能丢失部分现场)${NC}"echo-e"${YELLOW}若需重启,可执行:${NC}"if[-n"$COMPOSE_CMD"];thenecho"${COMPOSE_CMD}restart${TARGET}"elseecho" docker restart${CONTAINER_ID}"fiecho-e"${YELLOW}(建议:若业务受损持续,先执行重启,保留本脚本输出用于事后分析。)${NC}"fi# ======================================================================# 步骤3:奥卡姆剃刀分流 —— 根据最简证据直接导向根因# 哲学依据:“如无必要,勿增实体”。根据退出码与 OOMKilled 直奔最常见病因,# 避免盲目执行大量无关检查。# ======================================================================echo-e"\n${GREEN}[步骤3] 奥卡姆剃刀分流诊断${NC}"# 手工检验步骤提醒:如果需要更详细的 Nginx 错误日志,可进入容器或宿主机挂载卷查看echo-e"${YELLOW}手工检验路径:Nginx 错误日志可能位于容器内 /var/log/nginx/error.log 或宿主机挂载卷。${NC}"echo" docker exec${CONTAINER_ID}cat /var/log/nginx/error.log (若容器可运行)"echo" 或检查数据卷位置:docker inspect${CONTAINER_ID}| jq .[0].Mounts"if["$OOM_KILLED"=="true"];then# -------------------------------# 3a. 内存耗尽(OOM Killer)# 奥卡姆剃刀:OOMKilled=true,问题就是内存不足,无需先查磁盘# -------------------------------echo-e"\n${RED}[奥卡姆剃刀] OOMKilled=true,容器因内存不足被宿主机杀死。${NC}"echo-e"${BLUE}3a.1 检查系统 OOM 日志,找出被杀进程详情${NC}"echo-e"${YELLOW}手工检验步骤:执行以下命令查看 OOM 记录,确定是 Nginx 自身还是其他进程耗尽内存。${NC}"echo" grep -i 'out of memory' /var/log/messages /var/log/syslog 2>/dev/null"echo" dmesg | grep -i oom"# 自动提取最近一次 OOM 事件(整体论:关联容器死亡时间)echo-e"${BLUE}尝试自动提取相关 OOM 记录:${NC}"dmesg|grep-i"killed process"|tail-5echo-e"\n${BLUE}3a.2 当前宿主机内存状态${NC}"free-hecho-e"\n${BLUE}3a.3 检查 docker-compose 文件中的内存限制${NC}"echo-e"${YELLOW}手工检验步骤:查看 docker-compose.yml 中 nginx 服务的 mem_limit 或 deploy.resources.limits.memory${NC}"echo" grep -A 10 '${TARGET}:' docker-compose.yml"echo-e"\n${YELLOW}[辨证分析] 如果 Nginx 内存配置合理,则可能是其他容器内存泄漏拖垮宿主机。${NC}"echo" 检查所有容器内存使用: docker stats --no-stream"elif["$EXIT_CODE"=="137"];then# 退出码 137 = 128+9 (SIGKILL),很大概率也是 OOM,但 OOMKilled 字段可能为 false(如 docker kill)echo-e"${RED}[奥卡姆剃刀] 退出码 137 (SIGKILL),可能原因:OOM Killer 或手动 docker kill。${NC}"echo-e"${YELLOW}请结合上面收集的 dmesg 判断是否存在 OOM 记录。若无,则可能是人为或编排系统杀死。${NC}"else# -------------------------------# 3b. 应用自身错误或配置问题# 奥卡姆剃刀:直接查看 Nginx 错误日志中的 crit/error 级别信息# -------------------------------echo-e"\n${BLUE}3b.1 奥卡姆剃刀:直接从容器日志中检索关键错误${NC}"# 尝试从之前收集的日志或重新获取dockerlogs"$CONTAINER_ID"2>&1|grep-iE"emerg|alert|crit|error"|tail-20echo-e"${YELLOW}手工检验步骤:如果上述信息不足,请进入宿主机挂载卷查看完整 error.log。${NC}"echo-e"\n${BLUE}3b.2 常见应用错误分流${NC}"# 检测典型错误模式(实用主义:基于常见问题模式匹配)ERR_LOG=$(dockerlogs"$CONTAINER_ID"2>&1)ifecho"$ERR_LOG"|grep-qi"no space left on device";thenecho-e"${RED}[磁盘空间] 日志中检测到 'No space left on device'${NC}"echo-e"${YELLOW}奥卡姆剃刀:直接检查磁盘空间与 inode。${NC}"echo-e"${BLUE}磁盘空间检查:${NC}"df-hecho-e"\n${BLUE}Inode 检查:${NC}"df-iecho-e"${YELLOW}手工检验步骤:检查 Nginx 日志目录是否占用大量 inode,执行:${NC}"echo" ls -l /path/to/mounted/logs | wc -l"elifecho"$ERR_LOG"|grep-qi"permission denied";thenecho-e"${RED}[权限问题] 日志中检测到 'Permission denied'${NC}"echo-e"${YELLOW}手工检验步骤:检查容器内 nginx 用户 uid 与挂载卷权限的匹配。${NC}"echo" docker exec${CONTAINER_ID}id nginx (若容器可运行)"echo" 检查宿主机挂载目录权限: ls -ld /宿主机/挂载点"elifecho"$ERR_LOG"|grep-qi"address already in use";thenecho-e"${RED}[端口冲突] 检测到端口被占用。${NC}"echo-e"${YELLOW}手工检验步骤:查看当前端口监听情况${NC}"echo" netstat -tulpn | grep <端口号>"elifecho"$ERR_LOG"|grep-qi"cannot open.*certificate\|ssl";thenecho-e"${RED}[证书/配置问题] 检测到 SSL 证书或相关错误。${NC}"echo-e"${YELLOW}手工检验步骤:验证证书文件是否存在及权限,执行 'docker exec${CONTAINER_ID}ls -l /etc/nginx/certs'${NC}"fifi# ======================================================================# 步骤4:整体论关联资源与系统状态# 哲学依据:整体论告诉我们,系统大于部分之和。容器死亡可能与宿主机 CPU、磁盘或# 其他服务的交互涌现行为相关,必须进行关联分析。# ======================================================================echo-e"\n${GREEN}[步骤4] 整体论资源与状态关联分析${NC}"echo-e"${BLUE}4.1 宿主机全局资源视图${NC}"echo"CPU 和内存摘要:"top-bn1|head-5echo-e"\n磁盘使用:"df-hecho-e"\nInode 使用:"df-iecho-e"\n${BLUE}4.2 Docker 整体状态${NC}"dockerstats --no-stream--all2>/dev/null|head-10echo-e"\n${BLUE}4.3 寻找与故障时间吻合的系统事件(整体论关联)${NC}"echo-e"${YELLOW}手工检验步骤:确定容器退出时间,与系统日志/监控图表进行比对。${NC}"FINISHED_AT=$(dockerinspect--format='{{.State.FinishedAt}}'"$CONTAINER_ID"2>/dev/null)echo" 容器退出时间:$FINISHED_AT"echo" 请检查以下内容在该时间点前后是否有异常:"echo" - 系统日志: journalctl --since=\"YYYY-MM-DD HH:MM:SS\"--until=\"...\""echo" - Docker 守护进程日志: journalctl -u docker"echo" - 监控系统 CPU/磁盘 I/O 尖刺"# ======================================================================# 步骤5:整体论人工深入 —— 全链路与涌现行为# 哲学依据:整体论要求跨服务视图,单体日志无异常时,可能是上游超时或# 调用链累积延迟导致的涌现行为。# ======================================================================echo-e"\n${GREEN}[步骤5] 整体论人工检验:全链路与涌现行为${NC}"echo-e"${YELLOW}如经上述检查仍未定位根因,请执行以下分布式系统排查:${NC}"echo"1. 全链路追踪检查:"echo" - 在分布式追踪系统(如 Jaeger, Zipkin)中查找故障时间窗的 trace。"echo" - 定位慢请求,查看 Nginx 上游调用耗时是否超出 proxy_read_timeout 等设置。"echo"2. 上游服务状态:"echo" - 检查 Nginx 代理的所有 upstream 服务在故障时刻的健康状况。"echo" - 是否存在级联超时或线程池耗尽。"echo"3. 网络连接:"echo" - 检查容器间网络是否稳定,有无丢包或防火墙规则变动。"echo"4. 配置文件变更历史:"echo" - 结合版本控制查看 nginx.conf 及 docker-compose.yml 的近期变更。"# ======================================================================# 步骤6:道家无为 —— 从源头构建韧性# 哲学依据:最好的排查是不必排查。“无为”倡导顺应故障必然发生的天道,# 通过自愈、限制和隔离来让系统自然恢复。# ======================================================================echo-e"\n${GREEN}[步骤6] 道家无为:构建韧性系统建议${NC}"echo-e"${YELLOW}请检查并实施以下优化,以减少未来紧急排查:${NC}"echo"1. 自愈重启策略:"echo" 在 docker-compose.yml 中添加 restart: unless-stopped 或 always"echo"2. 资源限制:"echo" 为 Nginx 服务设置合理的内存/CPU 限制 (mem_limit, cpus)。"echo"3. 健康检查:"echo" 配置 Docker 健康检查 (healthcheck) 使编排系统能自动重启不健康的容器。"echo"4. 日志轮转:"echo" 确保容器日志及 Nginx 访问日志配置了轮转,避免磁盘/inode 耗尽。"echo"5. 混沌工程验证:"echo" 在测试环境定期注入故障(杀容器、断网),验证系统自愈能力。"echo-e"\n${BLUE}========== 诊断脚本执行完毕 ==========${NC}"echo-e"${GREEN}请根据上述输出和手工检验步骤继续深入分析。${NC}"
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 4:28:43

多模态大模型驱动CV智能涌现:技术原理与应用实践

最近在AI技术社区中&#xff0c;"智能涌现"这个概念被频繁提及&#xff0c;特别是随着多模态大模型的快速发展&#xff0c;计算机视觉&#xff08;CV&#xff09;领域正经历着前所未有的变革。作为长期关注AI技术演进的技术从业者&#xff0c;我深切感受到CV技术正在…

作者头像 李华
网站建设 2026/7/12 4:27:45

项目深度分析报告--来自智谱Agent模式

一、项目概览 1.1 项目定位 gliding_horse&#xff08;流马&#xff09;是一个用 Rust 编写的"Agent OS"&#xff08;智能体操作系统&#xff09;&#xff0c;作者将其定位为"以 CPU 架构为隐喻的智能体编排系统"。项目试图将操作系统的设计理念&#xff0…

作者头像 李华
网站建设 2026/7/12 4:27:39

从零开始学Python:模块导入+range()函数,这是你入门的第一道坎!

一、模块导入&#xff08;前置知识&#xff09;在开始学习分支与循环之前&#xff0c;我们先了解Python中的模块导入机制。什么是模块&#xff1f;模块就是一个.py文件&#xff0c;包含了Python定义和语句。通过导入模块&#xff0c;可以使用其他文件中定义的功能。比如我们先在…

作者头像 李华
网站建设 2026/7/12 4:27:22

梅西要解的不是瑞士防线,而是一只不断收紧的钟

导语&#xff5c;四年前&#xff0c;阿根廷用激情赢得世界杯&#xff1b;四年后&#xff0c;他们必须学会在时间、体能与期待的夹击中卫冕。北京时间7月12日&#xff0c;堪萨斯城的夜色里&#xff0c;斯卡洛尼面对的不是一支急于创造奇迹的瑞士&#xff0c;而是一台耐心等待冠军…

作者头像 李华
网站建设 2026/7/12 4:26:47

L3自动驾驶牌照背后的电子电气架构真相

1. 这不是“能用就行”的功能&#xff0c;而是整车电子电气架构的照妖镜最近朋友圈刷屏的“L3级自动驾驶获准上路”消息&#xff0c;很多人第一反应是&#xff1a;终于能放手开车了&#xff1f;赶紧换车&#xff01;但作为在智能驾驶系统集成一线干了12年的老工程师&#xff0c…

作者头像 李华
网站建设 2026/7/12 4:23:13

高匿名/透明代理原理对比——代理类型、匿名级别、X-Forwarded-For、检测方法与代理类型对比表

文章目录 每日一句正能量 一、引言:为什么代理匿名级别决定爬虫生死 二、HTTP代理通信流程与匿名级别原理 2.1 透明代理(Transparent Proxy) 2.2 匿名代理(Anonymous Proxy) 2.3 高匿代理(Elite/High Anonymous Proxy) 三、代理类型对比表 四、X-Forwarded-For 传递机制…

作者头像 李华