深圳访问新加坡服务器SSH逐键卡顿,如何分层定位网络延迟?
深圳到新加坡的 SSH 连接中,如果终端每敲一个键都要等待约半秒,影响通常不只是“登录慢”,而是命令输入、交互式程序、日志查看和故障处理都会变得困难。持续的 500 毫秒级卡顿不能简单归因于服务器距离远:正常跨地域访问会有基础 RTT,但逐键等待还可能叠加了丢包重传、路由拥塞、IPv4/IPv6 路径差异、服务器资源争用,甚至是 Shell 或业务程序自身的响应延迟。
排查时应把 SSH 看成一条分层链路:本地网络负责把数据送出,DNS 决定连接到哪个地址,路由决定经过哪些网络,丢包和抖动决定数据是否需要重传,服务器资源决定 SSHD 和终端是否及时处理,最终的 Shell 或应用则决定交互内容何时返回。只有逐层对照证据,才能判断问题究竟在深圳侧、新加坡侧,还是中间路径。
一、先确认“逐键卡顿”究竟发生在哪里
区分连接建立慢和输入响应慢
先不要修改 SSH 配置、服务器防火墙或路由策略,记录一次完整故障过程。至少区分以下几种情况:
- 输入用户名、密码前就等待很久;
- 已经进入 Shell,但每个字符回显都延迟;
- 普通 Shell 命令可以执行,只有
vim、top、数据库终端等交互程序卡顿; - 敲键本身正常,但按回车后命令很久才返回;
- 只有某一台深圳电脑卡顿,其他网络访问正常;
- 多台电脑、不同网络访问同一台新加坡服务器都卡顿。
这几种现象对应的排查方向并不相同。登录前等待,通常优先查看 DNS、地址族选择、SSH 认证和服务器登录流程;逐字符回显延迟,更接近 RTT、丢包、TCP 重传或伪终端处理问题;只有某个应用卡顿,则不能继续把责任全部归给网络。

可以先用非交互命令测试连接建立和远端执行时间。下面的结果只是命令用法示例,地址和账号需要替换为实际值:
time ssh -o ConnectTimeout=10 user@203.0.113.10 'printf "remote-ok\n"'
这条命令主要观察建立连接、认证和执行一个简单命令的总耗时。如果它很快,但登录后逐键回显很慢,问题就不一定在 DNS 或 TCP 三次握手阶段。
同时记录以下信息:
- 故障发生的日期、时间和时区;
- 深圳侧公网出口 IP、使用的运营商和接入方式;
- 服务器公网 IPv4、是否存在 IPv6;
- 使用域名连接还是直接使用 IP;
- 是所有终端都卡顿,还是某一种 SSH 客户端卡顿;
- 故障是否持续,还是每隔一段时间出现;
- 同一时刻是否有备份、发布、批量下载或资源密集型任务。
用本地终端作对照
在远程 SSH 会话中输入一个简单命令,再在本地 Shell 中输入同样的内容。若本地终端也出现输入延迟,优先检查电脑 CPU、内存、终端软件和本地网络;若本地完全正常,只有远程会话卡顿,才继续沿着网络和服务器方向排查。
如果使用图形化 SSH 客户端,也可以用系统自带的 OpenSSH 客户端作一次对照。不同客户端对终端回显、压缩和伪终端的处理方式可能不同,但客户端差异不能替代网络证据。
二、建立原因树,避免被单一现象误导
可以先按“本地—解析—路径—传输—服务器—应用”建立原因树,再根据观测结果缩小范围。
| 层级 | 典型原因 | 更有价值的观察依据 | 下一步 |
|---|---|---|---|
| 深圳本地网络 | Wi-Fi 干扰、网关丢包、出口拥塞、终端资源不足 | 本地网关 Ping 是否丢包,换有线或其他接入后是否恢复 | 先排除本地链路 |
| DNS 与地址选择 | 域名解析到不同地址、IPv6 路径异常、解析超时 | 域名和 IP 的连接结果是否不同,IPv4 与 IPv6 是否差异明显 | 分别测试 A、AAAA、IPv4、IPv6 |
| 路由 | 跨境路径绕行、某段拥塞、不同运营商路径差异 | traceroute、mtr、TCP 探测的末端 RTT 与路径变化 | 判断延迟在哪一段开始升高 |
| 丢包与抖动 | 中间链路丢包、队列拥塞、TCP 重传 | 末端丢包、RTT 波动、TCP retrans 计数 | 与 SSH 卡顿时间对齐 |
| 服务器系统 | CPU、内存、Swap、磁盘 I/O、虚拟化争用 | vmstat、iostat、top、系统日志 | 判断 SSHD 是否被资源拖慢 |
| Shell 或应用 | 启动脚本、提示符脚本、交互程序等待外部服务 | 简单命令正常、特定 Shell 或应用异常 | 用干净 Shell 和最小命令对照 |
这里有一个容易忽略的边界:DNS 通常只影响“连接到哪里”和“连接建立前后”,不会在已经建立的 SSH 会话中为每一个按键重新解析域名。因此,若登录后持续逐键延迟,不能仅凭“重新解析域名很慢”来解释全部现象。
三、先排除深圳侧本地网络
检查默认网关和本地丢包
如果本地网关都无法稳定响应,继续分析新加坡服务器没有意义。Linux 可以先查看默认路由,再 Ping 网关;macOS 和 Windows 的命令略有区别。
Linux 示例:
ip route
找到 default via 后,对其中的网关地址进行测试:
ping -c 30 192.168.1.1
macOS 示例:
route -n get default
ping -c 30 192.168.1.1
Windows PowerShell 示例:
ipconfig
ping 192.168.1.1 -n 30
192.168.1.1 只是示例地址,应替换为实际默认网关。局域网网关在有线环境下通常应保持低延迟且基本无丢包;如果这里已经出现明显丢包或延迟突增,应先处理无线信号、网线、交换设备、家庭路由器或本地终端负载。
然后再对服务器 IP 做测试:
SERVER_IP="203.0.113.10" # 示例地址,实际替换
ping -c 30 "$SERVER_IP"
Windows:
$ServerIp = "203.0.113.10" # 示例地址,实际替换
ping $ServerIp -n 30
本地网关正常、服务器地址出现波动,说明问题更可能位于公网出口、跨境路径或新加坡侧。但 Ping 使用的是 ICMP,部分网络设备可能限速或不优先处理 ICMP,因此它只能作为一项证据,不能单独证明 SSH 的 TCP 22 端口也存在相同丢包。
对比不同接入方式
在不改变服务器配置的前提下,可以做低风险的对照:
- 有线网络与 Wi-Fi 对比;
- 公司出口与家庭宽带对比;
- 同一网络下不同电脑对比;
- 同一电脑在不同时间段对比;
- 域名访问与直接 IP 访问对比。
如果只有一台电脑卡顿,服务器和跨境路径的可能性会下降,应检查本机 CPU、内存、终端渲染、输入法以及安全软件的网络检查行为。如果同一出口下多台设备同时卡顿,而更换出口后恢复,应重点关注本地运营商出口或该时段的公网路径。
四、检查 DNS、IPv4 和 IPv6 的地址选择
域名连接慢,不等于 SSH 链路慢
先查看域名解析结果:
Linux 或 macOS:
dig +time=2 +tries=1 example.com A
dig +time=2 +tries=1 example.com AAAA
Windows PowerShell:
Resolve-DnsName example.com -Type A
Resolve-DnsName example.com -Type AAAA
如果域名同时存在 A 和 AAAA 记录,SSH 客户端可能优先尝试 IPv6。此时可以分别测试:
ssh -4 -vvv -o ConnectTimeout=10 user@example.com
ssh -6 -vvv -o ConnectTimeout=10 user@example.com
-vvv 会输出连接阶段的详细调试信息。示例中的域名、用户名和地址均需替换,输出内容可能包含主机名、地址和认证流程信息,提交给他人分析前应先脱敏。
判断方式如下:
- 域名连接慢,直接使用 IPv4 地址明显改善:优先检查 DNS 返回的地址、IPv6 路由或地址族选择;
- IPv4 和 IPv6 都慢,且目标 IP 相同:DNS 不是主要根因,应转向路由和丢包;
- 只有首次连接慢,登录后输入正常:可能是 DNS 查询、主机名反向解析或认证阶段等待;
- 已进入 Shell 后每个按键都慢:不能把问题归因于普通 DNS 查询。
服务器端也可能在 SSH 登录时进行客户端地址的反向解析,导致登录前等待。这个现象通常表现为“连接建立或认证前慢”,而不是稳定地为每个键增加相同延迟。不要在没有日志证据的情况下直接修改 SSHD 的解析或认证配置,尤其是生产服务器,应先备份配置并准备回滚。
五、用路由和 MTR 找出延迟开始的位置
先看路径,再看某一跳的数字
Linux:
traceroute -n -q 3 -w 1 203.0.113.10
macOS:
traceroute -n -q 3 203.0.113.10
Windows:
tracert -d 203.0.113.10
其中 -n 或 -d 用于避免对每一跳进行反向 DNS 解析,让结果更容易比较。
如果系统安装了 mtr,可以连续采样:
mtr -rwzc 100 203.0.113.10
在 ICMP 结果不稳定、但需要更贴近 SSH 端口的情况下,可以尝试 TCP 探测:
sudo mtr -rwzc 100 -T -P 22 203.0.113.10
部分系统的 mtr 版本不支持相同参数,执行前应查看 mtr --help。这类命令通常需要管理员权限,但只是在发送探测包,不涉及服务器配置修改。
正确理解 MTR 的丢包
MTR 中某个中间节点显示 20% 丢包,并不代表端到端真的丢了 20%。很多路由器会降低对 TTL 超时报文或 ICMP 的处理优先级,导致某一跳响应不完整;如果后续各跳和最终目标都没有同步出现丢包,这一跳本身通常不是故障点。
更有价值的是观察:
- 丢包是否从某一跳开始,并一直延续到最终目标;
- 末端目标的平均 RTT 和最大 RTT 是否明显升高;
- 延迟升高是否与 SSH 逐键卡顿发生在同一时间;
- 不同时间采样时,路径是否发生变化;
- 从不同深圳网络测试时,异常是否出现在不同的中间节点。
可以按下面的方式理解结果:

| 观察结果 | 更可能的解释 |
|---|---|
| 中间某一跳丢包,后续和目标无丢包 | 多数情况下是中间设备限制探测响应,不足以证明链路故障 |
| 从某一跳开始 RTT 升高,之后各跳和目标都保持较高 | 该段之后可能存在排队、绕路或跨网拥塞 |
| 目标地址持续丢包,且 SSH 同时出现重传 | 网络路径或目标侧入口链路存在实际传输问题 |
| ICMP 路径正常,TCP 22 探测异常 | 可能是端口路径策略、TCP 入口拥塞或 ICMP 与 TCP 路径处理不同 |
| 路由每次变化较大,延迟随路径变化 | 可能是动态选路、运营商互联或时段性拥塞 |
深圳到新加坡的公网 RTT 会受运营商、线路、地址段和时段影响,不能用一个固定数字判断正常或异常。通常应先建立同一出口、同一目标的基线。如果平时为几十到低百毫秒,故障时持续接近 500 毫秒并伴随明显抖动,就比“距离远”更值得关注;如果基础 RTT 本身已经较高,则要进一步看是否存在额外丢包和排队。
六、确认是否为丢包、抖动或 TCP 重传
SSH 的交互输入通常要经过远端伪终端处理,再把回显数据返回客户端。若输入包或回显包丢失,TCP 需要等待重传;当重传计时器、网络抖动和队列等待叠加时,用户就可能感觉“每按一下都停半秒”。

因此,不能只看平均 Ping。还要关注:
- 最大 RTT 是否远高于平均 RTT;
- 连续 Ping 是否出现成片超时;
- 同一时间 SSH 是否频繁卡顿;
- TCP 连接是否出现重传;
- 服务器返回是否正常,但客户端收到数据很晚。
Linux 上可以查看当前 TCP 连接的一些统计信息:
ss -ti | grep ':22'
不同版本的 iproute2 输出字段略有差异,通常可以关注 rtt、rto、retrans 等字段。该命令可能列出多条 22 端口连接,需要结合目标地址和连接状态识别对应会话。
示例输出仅用于解释字段含义:
cubic wscale:7,7 rto:480 rtt:86/24 retrans:2/5
这里的 rtt:86/24 可理解为当前 RTT 约 86 毫秒、波动估计约 24 毫秒;retrans 出现增长则说明存在重传迹象。示例不是任何实际环境的检测结果,也不应仅凭一次输出下结论。
如果 Ping 结果平稳、MTR 也没有末端丢包,但 SSH 仍然逐键卡顿,可能存在以下情况:
- ICMP 和 TCP 22 经过不同的处理路径;
- 客户端终端或 SSH 客户端自身处理缓慢;
- 服务器 CPU、I/O 或虚拟化资源被占用;
- 远端 Shell 或交互式程序在等待外部资源。
七、检查新加坡服务器的系统负载
观察 CPU、内存、I/O 和虚拟化争用
进入服务器后,先执行只读检查,不要为了验证网络问题直接重启 SSH 服务或修改防火墙。
date -Is
uptime
nproc
free -h
vmstat 1 10
如果系统已安装 iostat,可以继续查看磁盘和设备等待:
iostat -xz 1 10
重点关注以下指标:
vmstat中r长时间高于可用 CPU 线程数,可能存在运行队列堆积;si、so持续有值,说明发生 Swap 换入换出,内存压力较大;wa较高,说明进程在等待磁盘 I/O;st较高,说明虚拟机可能受到宿主机 CPU 争用;free -h中可用内存很低,且 Swap 持续增长;iostat中设备利用率长期接近饱和,响应时间明显升高。
uptime 中的 load average 不能直接等同于网络延迟。负载高可能来自 CPU、磁盘或不可中断 I/O 等不同原因,需要与 vmstat、top 或 iostat 一起判断。相反,即使负载不高,也不能完全排除网络丢包。
区分 SSHD 受阻和普通业务进程受阻
如果具备控制台、第二个管理会话或其他安全的本地管理方式,可以做对照:
- 服务器本地执行简单 Shell 命令是否立即返回;
- 另一条 SSH 会话是否也逐键卡顿;
- 只有某个账号卡顿,还是所有账号都卡顿;
- 服务器高负载是否与卡顿时间一致;
- SSHD 日志中是否有认证超时、连接重置或资源错误。
不同发行版的服务名可能是 sshd 或 ssh,先确认实际服务名再查看状态:
systemctl list-units --type=service | grep -E 'ssh(d)?'
查看状态和近期日志时使用只读命令:
systemctl status sshd --no-pager
journalctl -u sshd --since "10 minutes ago" --no-pager
如果系统实际服务名是 ssh,将命令中的 sshd 替换为 ssh。日志只能作为辅助证据;没有日志并不代表网络一定正常,也不应因为一次日志错误就直接重启服务。
八、把 Shell 和应用响应从网络问题中分离出来
用最小远程命令做对照
SSH 连接正常、简单命令返回及时,但进入完整 Shell 后逐键卡顿,常见原因可能在登录脚本、提示符或交互式程序中,例如:
.bashrc、.zshrc中执行了外部命令;- Shell 提示符每次刷新都执行 Git 状态检查;
- 提示符脚本访问了慢速文件系统或远程资源;
- 终端复用程序中的某个会话状态异常;
- 交互式应用使用了原始终端模式,并等待后端响应;
- 应用每次输入都需要查询数据库、文件系统或其他服务。
可以用非交互命令和伪终端命令做对比:
time ssh -o RequestTTY=no user@203.0.113.10 'printf "no-pty-ok\n"'
time ssh -tt user@203.0.113.10 'printf "pty-ok\n"'
如果两条命令都很快,但进入某个 Shell 或应用后才卡顿,网络路径不是唯一嫌疑。还可以在维护窗口中使用一个不加载常规配置的最小 Shell 进行对照:
ssh -tt user@203.0.113.10 'env -i HOME="$HOME" TERM="${TERM:-xterm}" PATH=/usr/bin:/bin /bin/sh'
该命令只是隔离测试示例。生产环境中应先确认账号权限、Shell 路径和业务影响,测试完成后退出会话,不要把它当成永久登录配置。
根据“受影响对象”判断边界
- 所有账号、所有 Shell 都卡顿:更偏向网络、服务器资源或 SSHD;
- 只有一个账号卡顿:检查该账号的 Shell 配置、提示符和启动脚本;
- 只有某个交互程序卡顿:检查程序自身的输入处理和后端依赖;
- 简单命令返回快,但按键回显慢:重点查看 TCP 重传、伪终端和客户端;
- 按键回显快,但回车执行慢:重点检查命令本身、磁盘、数据库和外部服务;
- 只有通过域名连接时异常:继续核对解析结果、IPv6 和目标地址差异。
这一步能避免常见误判:服务器上的某个程序响应慢,并不自动意味着深圳到新加坡的网络延迟高。
九、根据证据定位根因
可以用下面的判断矩阵收敛结论:
| 已观察到的组合 | 优先定位方向 | 处理建议 |
|---|---|---|
| 本地网关有丢包,服务器测试也异常 | 深圳本地链路 | 先处理 Wi-Fi、网关、终端或本地出口 |
| 本地网关正常,多个目标都同时变慢 | 本地运营商出口或公网拥塞 | 对比其他时段和其他网络,保留时间点证据 |
| 只有某个服务器 IP 的末端 MTR 延迟和丢包升高 | 到该地址的路由或服务器入口 | 向服务器服务商提交完整探测结果 |
| 不同网络访问同一服务器都卡顿,服务器资源也很高 | 服务器系统资源 | 结合 CPU、内存、I/O 和任务时间线处理 |
| 域名慢、直接 IPv4 快,或 IPv6 慢而 IPv4 正常 | DNS 或地址族 | 核对 A/AAAA、路由和客户端选择 |
| TCP 连接建立快,简单命令快,只有某个应用卡顿 | Shell 或应用 | 检查启动脚本、提示符和应用后端 |
| ICMP 正常,但 TCP 22 有重传或连接卡顿 | TCP 端口路径或入口策略 | 使用 TCP 探测,并让服务商检查端口链路 |
| RTT 约 80 毫秒,但逐键等待约 500 毫秒且有重传 | 丢包、抖动或队列等待 | 重点对齐 SSH 卡顿时间和 TCP 统计 |
如果服务器托管在 A5IDC,提交工单时不要只写“SSH 很卡”。更有用的信息包括:
- 深圳侧公网出口 IP 和运营商;
- 目标服务器 IP、使用 IPv4 还是 IPv6;
- 精确到分钟的故障时间,并注明时区;
- 30 次或 100 次 Ping 结果;
traceroute、mtr或 TCP 22 探测结果;ssh -vvv中连接阶段的关键片段;- 服务器端
vmstat、iostat、uptime的时间对应关系; - 是一个客户端异常,还是多个网络同时异常。
敏感信息应先脱敏,不要提交密码、私钥、完整认证凭据或无关业务日志。
十、验证恢复,而不是只看一次成功连接
定位到可能根因后,应一次只改变一个变量。例如先更换本地接入方式,再重复同一组测试;不要同时修改 DNS、SSH 配置、服务器规格和防火墙,否则即使恢复,也无法知道哪一项真正生效。
建议按以下顺序复核:
- 在原来的深圳网络和相近时段,重复 Ping、MTR 或 TCP 探测。
- 用同一个服务器 IP、同一个账号和同一个 SSH 客户端复测。
- 连续输入一段普通文本,观察逐键回显是否恢复。
- 执行简单远程命令,确认连接建立和命令返回时间。
- 查看末端丢包、RTT 波动和 TCP 重传是否同步下降。
- 对照服务器 CPU、内存、I/O 指标,确认资源压力没有转移成新的问题。
- 在至少几个不同时间窗口复测,避免把短暂的路由恢复误认为长期解决。
恢复验证应同时观察用户体验和底层指标。仅仅看到一次 ssh 命令成功,并不能证明链路已经稳定;也不能因为 Ping 恢复,就忽略 SSH TCP 连接仍有重传。
复发时应持续监控哪些点
对于经常从深圳访问新加坡服务器的业务,建议把监控拆成三类,而不是只监控服务器是否在线。
网络路径监控
- 从深圳侧或接近实际用户出口的位置,定时测试目标 IP 的 TCP 22 连接时间;
- 记录 RTT 的平均值、最大值和高分位变化;
- 统计末端丢包率,而不是只看中间某一跳;
- 分别记录 IPv4 和 IPv6 的结果;
- 记录不同运营商或不同出口的路径差异;
- 在异常时保存一份连续 MTR 或 TCP 探测结果。
阈值应以稳定时期基线为准。比如可将“连续多个采样窗口的 TCP 连接时间明显超过基线两倍”作为告警条件,而不是固定认定某个毫秒数一定异常。对交互式 SSH 而言,持续的末端丢包和明显 RTT 抖动通常比单次高延迟更值得告警。
服务器资源监控
至少关注:
- CPU 使用率和运行队列;
- 内存可用量、Swap 活动;
- 磁盘 I/O 等待和设备响应时间;
- 虚拟机 CPU steal;
- SSHD 连接数、认证失败和连接重置;
- 备份、发布、日志压缩等定时任务的执行时间。
监控时间必须统一时区,并确保服务器和采集端时间同步,否则网络异常、服务器高负载和用户反馈可能无法正确对齐。
应用交互监控
如果服务器承载数据库终端、运维控制台或其他交互式应用,还应单独记录:
- 简单 Shell 命令返回时间;
- 进入特定应用后的首屏时间;
- 输入后回显或提交结果的延迟;
- 应用访问数据库、文件系统和外部接口的耗时;
- 不同账号、不同 Shell 配置下的差异。
这样再次出现“每敲一个键卡半秒”时,就能迅速判断是深圳本地、跨境路径、新加坡服务器,还是某个应用分支,而不必从头凭感觉排查。


