Margrop
Articles178
Tags375
Categories23
1password AC AI AP API AppDaemon Aqara Caddy Cookie 认证 Cron Date Diagrams.net HA HADashboard HomeAssistant IP IPv4 Java LVM‑Thin Linux MacOS MiniMax MySQL NAS Nginx OpenAI OpenClaw OpenResty PPPoE PostgreSQL ProcessOn Proxmox VE SOCKS5 SSL Shell TTS TimeMachine UML Uptime Kuma VPN VPS Web Windows activate ad adb adblock agent aligenie aliyun alpine annotation aop authy autofs backup baidupan bash bitwarden boot brew browser caddy2 cdn centos cert certbot charles chat chrome classloader client clone closures cloudflare cmd command commit container crontab ctyun ddsm demo dependency deploy developer devtools dll dns docker domain download draw drawio dsm dump dylib edge exception export fail2ban feign firewall-cmd flow frp frpc frps fuckgfw function gcc gfw git github golang gperftools gridea grub gvt-g hacs havcs heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https idea image img img2kvm import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jni jnilib jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live low-code lvm lxc m3u8 mac macos mariadb markdown maven md5 microcode mirror modem modules monitor mount mstsc mysql n2n n5105 nas network nfs node node-red nodejs nohup notepad++ npm nssm ntp oop openfeign openssl os otp ovz packet capture pat pdf pem perf ping pip plugin png powerbutton print pro proxy pve pvekclean python qcow2 qemu qemu-guest-agent rar reboot reflog remote remote desktop renew repo resize retina root route router rule rules runtime safari sata scipy-notebook scoping scp server slmgr so socks source spk spring springboot springfox ssh ssl stash string supernode svg svn swagger sync synology systemctl tap tap-windows tapwindows telecom template terminal tls token totp tvbox txt ubuntu udisk ui undertow uninstall unlocker upgrade url v2ray vhd vim vlmcsd vm vmdk web websocket wechat windows with worker wow xiaoya xml yum zip 中国电信 云电脑 交换机 光猫 公网IP 内存 内网IP 升级 反向代理 启动 夏令时 天猫精灵 天翼云 安全 安装 容器 导入 小米 常用软件 广告屏蔽 序列号 应用市场 异常 打工 技术 抓包 描述文件 日记 时区 显卡虚拟化 智能家居 智能音箱 梯子 模块 流程 流程图 浏览器 漫游 激活 火绒 电信 画图 直播源 续期 网关 网络 网络风暴 群晖 腾讯 自动化 虚拟机 证书 路由 路由器 软件管家 软路由 运维 运维监控 配置 钉钉 镜像 镜像源 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客

Hitokoto

Archive

记一次服务连接超时的完整排查:从网络层到应用层的故障定位

记一次服务连接超时的完整排查:从网络层到应用层的故障定位

前言

在运维工作中,服务连接超时是一个常见但排查起来可能很棘手的问题。这种问题可能由多种原因导致:网络不通、防火墙阻止、连接池耗尽、服务负载过高、超时设置不合理等等。本文将详细记录一次关于服务连接超时的完整排查过程,从网络层到应用层,逐步定位问题根源,希望能给遇到类似问题的同学一些参考。

问题背景

业务场景

我们的基础架构中部署了多个服务,这些服务之间通过API进行通信。某日,用户反馈某服务无法正常访问,影响了业务正常运行。作为运维人员,收到告警后需要立即定位问题并恢复服务。

问题现象

  • 故障时间:近期某日
  • 故障表现:服务连接超时,无法正常访问
  • 异常状态
    • 服务进程正常运行
    • 端口正常监听
    • 本地访问正常
    • 远程访问超时
  • 影响范围:部分用户无法访问关键业务API

环境信息

设备 角色 状态
应用服务器 提供API服务 ✅ 运行中
调用方服务器 发起API请求 ✅ 运行中
负载均衡器 分发请求 ✅ 正常
数据库服务器 提供数据存储 ✅ 正常

排查过程

第一步:确认服务状态

首先确认服务本身是否正常运行。这是排查的第一步,也是最基本的一步。如果服务进程都不在,那后续的排查就没有意义了。

1
2
3
4
5
6
7
8
9
10
11
# SSH登录到应用服务器
ssh root@应用服务器IP

# 检查服务进程
ps aux | grep 服务名

# 检查端口监听
netstat -tlnp | grep 端口号

# 检查服务日志
tail -f /var/log/服务名.log

结果:服务进程正常运行,端口正常监听,日志无明显错误。初步判断服务本身没有问题,问题可能出在网络层或其他层面。

第二步:测试本地访问

在应用服务器本地测试服务是否正常响应。这一步是为了确认服务本身的功能是正常的,只是远程访问有问题。

1
2
3
4
5
6
7
8
# 测试本地回环访问
curl -I http://localhost:端口号/health

# 或者
wget -O- http://localhost:端口号

# 检查服务健康状态
curl http://localhost:端口号/api/health

结果:本地访问正常,服务响应正常。这说明服务本身没有问题,问题出在网络层面。

第三步:测试远程访问

从调用方服务器测试远程访问。这一步是为了模拟真实用户的访问场景,确认问题确实存在。

1
2
3
4
5
6
7
8
# 测试远程连接
curl -I http://应用服务器IP:端口号

# 测试端口连通性
telnet 应用服务器IP 端口号

# 或者使用 nc 命令
nc -zv 应用服务器IP 端口号 -w 5

结果:远程访问超时,连接无法建立。这证实了问题出在网络层面,需要进一步排查网络连通性。

第四步:排查网络层

检查网络连通性。这一步需要检查多个方面:网络是否可达、路由是否正确、防火墙是否阻止等等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 测试网络连通性
ping -c 3 应用服务器IP

# 路由追踪
traceroute 应用服务器IP

# 检查防火墙规则
iptables -L -n

# 检查SELinux状态
getenforce

# 检查系统连接数限制
cat /proc/sys/net/core/somaxconn

结果

  • ping 正常,无丢包
  • 路由正常,无异常跳数
  • 防火墙未阻止连接
  • SELinux未启用

网络层看起来也是正常的。这就很奇怪了。

第五步:深入排查

检查服务配置和连接状态。有时候问题可能出在服务的配置上,比如连接数限制、超时设置等等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 检查服务连接数
netstat -an | grep 端口号 | wc -l

# 检查服务进程状态
ps aux | grep 服务名

# 检查系统资源
top
free -h
df -h

# 检查磁盘IO
iostat -x 1 5

# 检查网络IO
sar -n DEV 1 5

结果:发现问题!服务进程存在大量连接,可能导致资源耗尽。具体表现为:

  • 连接数接近配置的最大值
  • 内存使用率较高
  • CPU使用率正常

第六步:定位根因

进一步分析发现问题的根本原因:

  1. 连接池耗尽:服务配置的最大连接数过低,当前连接数已经接近上限
  2. 超时设置不合理:调用方超时设置过短,服务器响应较慢时容易超时
  3. 重试机制缺失:失败后未及时重试,导致请求失败
  4. 资源不足:服务器负载较高,处理能力有限

解决方案

方案一:调整服务配置

修改服务配置文件,增加连接池大小和超时时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 修改服务配置文件
vi /etc/服务名/config.yml

# 调整连接池大小
max_connections: 1000 # 原来是 100
max_idle_connections: 200 # 新增

# 调整超时设置
timeout: 30000 # 30秒,原来是10秒
connect_timeout: 5000 # 5秒

# 调整线程池大小
worker_threads: 16 # 原来是4

方案二:优化调用方配置

在调用方增加重试机制和合理的超时设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Python 示例
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 设置重试策略
session = requests.Session()
retry = Retry(
total=3,
backoff_factor=0.5,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount(http://, adapter)
session.mount(https://, adapter)

# 设置合理的超时时间
response = session.get(
http://应用服务器IP:端口号/api,
timeout=(5, 30), # 连接超时5秒,读取超时30秒
headers={User-Agent: MyApp/1.0}
)

方案三:添加监控告警

部署完善的监控系统,及时发现和处理问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Prometheus 告警规则
groups:
- name: service_alerts
rules:
- alert: ServiceHighLatency
expr: http_request_duration_seconds > 5
for: 5m
labels:
severity: warning
annotations:
summary: "服务响应延迟过高"
description: "服务 {{ $labels.instance }} 响应延迟超过5秒"

- alert: ServiceHighConnection
expr: rate(service_connections_total[5m]) > 1000
for: 3m
labels:
severity: warning
annotations:
summary: "服务连接数过高"
description: "服务 {{ $labels.instance }} 连接数过高"

- alert: ServiceDown
expr: up{job="service"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "服务不可用"
description: "服务 {{ $labels.instance }} 已经停止运行"

方案四:优化数据库查询

有时候服务慢是因为数据库查询慢,需要优化SQL:

1
2
3
4
5
6
7
8
9
10
-- 开启慢查询日志
SHOW VARIABLES LIKE slow_query_log;
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;

-- 查看慢查询
SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;

-- 优化查询
CREATE INDEX idx_user_id ON orders(user_id);

一键排查脚本

如果你遇到了类似的服务连接超时问题,可以使用以下脚本进行快速排查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/bin/bash

# 服务连接超时排查脚本

TARGET_IP=$1
TARGET_PORT=$2

if [ -z "$TARGET_IP" ] || [ -z "$TARGET_PORT" ]; then
echo "用法: $0 <目标IP> <目标端口>"
exit 1
fi

echo "=== 服务连接超时排查 ==="
echo "目标: $TARGET_IP:$TARGET_PORT"
echo ""

echo "1. 检查服务进程..."
ps aux | grep -v grep | grep -E "(java|node|python|go)" | head -5
echo ""

echo "2. 检查端口监听..."
netstat -tlnp 2>/dev/null | grep $TARGET_PORT || ss -tlnp | grep $TARGET_PORT
echo ""

echo "3. 测试本地访问..."
curl -I http://localhost:$TARGET_PORT/health --connect-timeout 2 2>/dev/null || echo "本地访问失败"
echo ""

echo "4. 测试远程访问..."
curl -I http://$TARGET_IP:$TARGET_PORT/health --connect-timeout 5 2>/dev/null || echo "远程访问失败"
echo ""

echo "5. 检查网络连通性..."
ping -c 3 $TARGET_IP
echo ""

echo "6. 检查防火墙..."
iptables -L -n 2>/dev/null | grep $TARGET_PORT || echo "未找到防火墙规则"
echo ""

echo "7. 检查系统资源..."
echo "内存使用:"
free -h
echo ""
echo "磁盘使用:"
df -h | grep -v tmpfs
echo ""

echo "8. 检查连接数..."
netstat -an 2>/dev/null | grep $TARGET_PORT | wc -l
echo ""

echo "=== 排查完成 ==="

常见问题解答

Q:服务明明在运行,为什么连接超时?

A:可能的原因包括:网络不通、防火墙阻止、连接池耗尽、服务负载过高、超时设置不合理等。建议按本文的排查步骤逐一排查,从网络层到应用层,逐步缩小范围。

Q:如何快速判断是网络问题还是服务问题?

A:先在服务端本地尝试连接(localhost),如果本地可以连但远程不行,那基本就是网络问题。如果本地也连不上,那可能是服务本身的问题。

Q:连接超时该如何优化?

A:

  1. 增加连接池大小,避免连接耗尽
  2. 调整超时设置,给予足够的响应时间
  3. 添加重试机制,提高请求成功率
  4. 优化数据库查询,减少响应时间
  5. 使用缓存减少重复请求,降低后端压力

Q:如何避免类似问题再次发生?

A:

  1. 部署完善的监控系统,设置合理的告警阈值
  2. 定期进行压力测试,了解系统瓶颈
  3. 做好容量规划,确保资源充足
  4. 建立应急预案,确保出问题能快速恢复
  5. 定期审计配置,确保配置合理

Q:服务负载过高怎么办?

A:

  1. 增加服务实例,使用负载均衡分发请求
  2. 优化代码性能,减少资源消耗
  3. 扩容硬件资源,提升处理能力
  4. 启用缓存,减少数据库压力
  5. 异步处理非关键请求,提高响应速度

经验总结

  1. 排查要有层次:从网络到应用,从本地到远程,逐步缩小范围。不要盲目猜测,要用数据说话。

  2. 善用监控工具:监控系统能帮助快速定位问题。建议部署完整的监控体系,包括基础设施监控、应用监控、业务监控等。

  3. 做好容量规划:避免因资源不足导致的服务异常。定期评估系统容量,提前扩容。

  4. 重视日志分析:日志是排查问题的重要依据。建议统一日志格式,便于分析和检索。

  5. 建立应急预案:出问题时要能快速响应和恢复。制定详细的应急预案,并定期演练。

  6. 保持文档更新:将排查过程和解决方案记录下来,方便后续参考。文档是知识传承的重要手段。

延伸阅读

结语

服务连接超时是一个常见但可能由多种原因导致的问题。本文记录了一次完整的排查过程,重点在于:

  1. 先确认服务本身是否正常
  2. 再排查网络连通性
  3. 最后检查配置和资源

通过系统化的排查方法,我们可以快速定位问题根源并解决。希望这篇文章能帮到你。如果有问题,欢迎在评论区讨论。


作者:小六,一个在上海努力搬砖的程序员

Author:Margrop
Link:http://blog.margrop.com/post/2026-03-05-troubleshooting-api-timeout/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可