前几天处理了一个挺典型的故障,背景是这样的:一台长期跑着OpenClaw的Ubuntu服务器,业务网关每天要处理大量大模型API调用,之前一直正常。后来为了远程访问内网里的几台设备,我在服务器上装了Tailscale,本来只是想组个私网。结果第二天早上,OpenClaw的日志里开始刷屏:LLM request timed out,业务网关API请求大面积超时,多轮对话基本没法用。蹊跷的是SSH、网站、内网服务都好好的,唯独所有需要连接公网LLM服务商的请求全军覆没。我试着把Tailscale停掉,OpenClaw瞬间恢复正常;再把Tailscale启起来,超时立刻回来。如果你也遇到过OpenClaw安装Tailscale后LLM请求超时,或者正打算在Agent服务器上引入Tailscale,这篇复盘可以帮你省下一整天的折腾。
1. 故障现象与影响范围:先从日志里的LLM request timed out说起
1.1 现场还原:OpenClaw业务网关超时日志长什么样
当时打开OpenClaw的日志文件,最先看到的是连续翻滚的错误记录,核心内容大概是下面这样的:
[ERROR] gateway: llm request timed out after 60000ms [ERROR] openclaw: agent failed before reply: session file locked (timeout 60000ms)第一行说明业务网关发出了LLM调用,等了60秒没等到响应;第二行是同一个会话的下一个请求因为上一个请求还没结束,会话文件被锁住,等待60秒后放弃。这两条其实是同一根因的连锁表现:底层是网络请求超时,上层是会话锁等待超时。如果不看底层,只盯着第二行容易误判成“OpenClaw自身出Bug”或者“并发冲突”。
表面症状也很有迷惑性:OpenClaw进程没有崩溃,CPU和内存占用正常,页面也能打开;从Teams或客户端发消息,半天没有回复,过了很久才弹一个超时提示。很多人第一反应是“API Key是不是过期了”“模型服务商是不是挂了”“OpenClaw参数是不是被改坏了”,实际上这些都没问题。我处理过不少类似案例,这条经验很重要:当进程本身还活着、页面还能访问,只有外部LLM调用超时时,优先怀疑网络层变更,而不是应用配置。尤其恰好在你刚装过网络工具之后,这个怀疑顺序几乎不会错。
1.2 影响范围:为什么只有LLM请求遭殃
这次故障最奇怪的地方在于,受影响面非常“精准”。和公网LLM服务商相关的功能全部超时:多轮对话、工具调用、知识库内容生成这些环节,全都绕不过外部大模型API。但服务器本地或内网相关的功能又都正常,比如Obsidian本地文件读取、内网服务调用、SSH远程登录,该通还是通。
这其实是理解故障的一把钥匙。OpenClaw这类Agent服务,大量工作要交给外部LLM完成,而LLM服务商提供的都是公网API,请求体通常还不小。相比之下,内网服务本来就在私网范围内,有些设备甚至还是通过Tailscale接入的,流量恰好走的是刚建立的虚拟链路,反而没有受网络栈变更影响。所以从使用者的角度看,就像“OpenClaw局部坏掉了”;从网络角度看,其实是服务器访问公网的路径被改了,而依赖公网的那部分功能最先暴露问题。
另外一个值得记录的现象是:停掉Tailscale后故障立刻消失,启动Tailscale后故障马上回归。这个规律基本把OpenClaw配置、API Key、模型服务商全排除了,问题被死死按在Tailscale对系统网络栈的改动上。后面要做的事情很明确:找出它到底改了什么,以及为什么这些改动会让LLM请求超时。
2. 根因分析:Tailscale安装后到底改了什么
2.1 四个必查的网络栈变更点
Tailscale安装并启动后,不是简单地“多了一块虚拟网卡”就完了。它为了让远程组网、访问内网子网、解析主机名这些能力生效,会主动改动系统的网络栈,常见的有四处:
第一,新增虚拟网卡tailscale0,并给它分配一个100.x.y.z形式的地址。这个网段是Tailscale内部使用的CGNAT段,意味着服务器从此多了一条通往私网虚拟链路的通道。第二,修改系统路由表。至少会加入一条指向100.64.0.0/10的私网段路由;如果这台机器被配置成了出口节点或者子网路由器,还可能添加或改写默认路由,甚至把整台服务器的公网流量都引到虚拟链路里。第三,接管DNS解析。启用MagicDNS后,/etc/resolv.conf里的nameserver可能会被改成100.100.100.100,所有域名解析都先经过Tailscale的虚拟DNS。第四,增加netfilter防火墙规则。为了支持子网路由转发,iptables里会出现Tailscale相关链的规则,在Docker环境下特别容易和已有的NAT规则打架。
附带还有一个容易忽略的变量:MTU。物理网卡默认MTU通常是1500,而Tailscale虚拟链路默认只有1280,小了两百多字节。这个差异平时不明显,遇到大请求时却很致命。
2.2 逐一排查:哪个变更最容易让业务网关超时
结合OpenClaw的调用链路,我梳理出四个最可疑的“肇事点”,每一个都能单独造成LLM request timed out。
第一个是默认路由被“拐”进虚拟链路。如果服务器启用了出口节点,访问任何公网地址都会先进入Tailscale的虚拟链路,再从出口节点那台机器出去。链路变长、跳数翻倍,加上出口节点的公网质量不一定有保障,LLM API这种高频公网请求很容易出现连接超时。这种情况的特征最明显:不只LLM超时,连curl访问其他公网网站也会超时或延迟极高。
第二个是DNS解析被MagicDNS接管。MagicDNS本来是为私网主机名解析设计的,如果它对公网域名的解析链路不理想,就会出现解析缓慢、解析失败,或者拿到一个不可达的地址。OpenClaw业务网关要连接各家LLM服务商,第一步就要解析域名,解析环节一旦出问题,后面全部白搭。这种情况的特征是:用dig查询公网域名很慢,或者返回的结果不符合预期。
第三个是MTU分片黑洞。LLM调用的请求体经常几十KB甚至上百KB,TCP会把这些数据切成分片。虚拟链路MTU只有1280,如果路径上禁止分片,或者路由器没有正确返回ICMP消息,这些大包会被悄悄丢弃。表现非常典型:小请求(比如简单的HTTP GET)能通,带长上下文的大请求必超时。
第四个是iptables规则与容器网络冲突。OpenClaw如果跑在Docker容器里,宿主机新增的Tailscale相关FORWARD和NAT规则可能会把容器出站流量错误地转发到tailscale0,数据发出去就没有回包,直到超时。这种情况的特征是:宿主机上curl正常,容器内curl超时。
2.3 为什么停掉Tailscale就恢复
这个现象很多人觉得玄,其实原理很简单。Tailscale执行tailscale down之后,会回收虚拟网卡上的地址,撤销它加过的路由规则和DNS配置,netfilter规则也会进入不生效状态。通俗地说,它把自己动过手的地方都恢复到接近安装前的样子,所以OpenClaw业务网关顿时畅通。故障复现这么“听话”,反而帮了大忙:它证明了问题不出在OpenClaw、不出在模型厂商,而是出在Tailscale对网络栈的修改上。
搞清楚这一点,后面就不慌了。既然不是应用层的问题,就不要反复去改OpenClaw的API Key、模型名、温度参数,那些都是无用功。接下来要做的,是用一套有条理的排查办法,把具体是哪一处网络栈改动导致的超时给揪出来。
3. 完整排查流程实录:从现象到根因
3.1 第一步:用curl对比测试确认故障边界
我先在OpenClaw服务器上直接测公网LLM服务商,用curl发几个最简单的HTTPS请求,每次限制10秒:
curl -I --max-time 10 https://api.deepseek.com curl -I --max-time 10 https://api.openrouter.ai curl -I --max-time 10 https://api.openai.com curl -I --max-time 10 https://open.bigmodel.cn记录返回的HTTP状态码和总耗时。然后执行tailscale down,把虚拟链路停掉,重新跑一遍同样的命令。两边一对比,结论非常直观:Tailscale启动时,这些公网API要么超时要么连接失败;Tailscale停止后,全部秒回正常状态码。这一步的价值是把“OpenClaw故障”重新定性为“服务器公网出口故障”,后续排查就不用再碰应用配置了。
与此同时,我在OpenClaw日志里区分了一下超时类型。如果错误信息是connect timeout,说明TCP连接根本没建立起来,重点查路由和防火墙;如果是read timeout,说明连接建立了但数据没回全,重点查MTU和链路质量。这一步很多人会跳过,但它能直接决定排查方向,省下大量瞎猜时间。实测下来,我这边的错误更多集中在连接建立阶段,初步把矛头指向路由和DNS。
3.2 第二步:从路由表与DNS里找线索
确认是网络层问题后,我立刻检查了系统的路由表:
ip route show结果发现默认路由还是走物理网关,没有变成tailscale0,说明这台机器没有被配置成出口节点,第一条“默认路由被拐走”的嫌疑基本排除。接着看DNS:
cat /etc/resolv.confnameserver已经被改成了100.100.100.100,这正是Tailscale MagicDNS的典型接管状态。再手动解析一下LLM服务商域名:
dig +short api.deepseek.com dig +short api.openrouter.ai解析结果能返回公网IP,但耗时明显偏长,而且偶尔出现解析慢到卡住的情况。问题到这里基本浮出水面:MagicDNS接管后,公网域名的解析链路变得不可靠,OpenClaw业务网关在发起LLM调用时,第一步解析就卡顿,后续自然全部超时。
这里插一句,排查DNS时不要只看“能不能解析”,还要看重试次数和耗时。DNS查询走了额外链路,返回慢一两点不一定致命,但如果每次都卡在临界值上,再叠加LLM请求本身的延迟,超时就成了必然。
3.3 第三步:MTU分片黑洞验证
路由表没问题,但连接层还是异常,我紧接着怀疑MTU。先看虚拟网卡当前的MTU:
ip link show tailscale0默认就是1280。于是做了一次标准的分片测试,用禁止分片模式向一个可靠公网IP发包:
ping -M do -s 1400 -c 3 223.5.5.5如果能通,说明路径上对1400字节的包没问题;如果包全部丢弃,基本可以断定是MTU问题。再配合一个实测手段:用curl构造一个较大的POST请求体访问LLM服务商,比如故意把上下文塞到几百KB,观察是否比小请求更容易卡死。实测下来,我这个案例里小请求能通、大请求必超时的现象不算特别明显,主要还是解析链路的问题,但MTU这个坑在Tailscale场景里太常见了,绝对不能跳过。尤其是OpenClaw这类Agent,上下文越长,请求体越大,MTU黑洞的杀伤力越强。
3.4 第四步:容器网络与防火墙规则交叉检查
我这边OpenClaw是直接用systemd服务跑在宿主机上的,没走Docker,所以容器网络嫌疑较轻。但如果你的OpenClaw是docker compose部署的,这一步是必查项。一个非常高效的排查动作是“容器内外对比测试”:
docker exec -it <openclaw容器名> curl -I --max-time 10 https://api.deepseek.com如果宿主机能通、容器内超时,问题十有八九出在Docker网桥和宿主机的iptables规则冲突上。再配合:
iptables-save | grep -i tailscale看Tailscale的规则是否出现在关键链里。另外还要确认宿主机的IPv4转发开关是打开的:
sysctl net.ipv4.ip_forward这个值如果是0,Tailscale子网路由模式下某些转发场景会直接失效,表现也可能是公网请求异常。走完这四步检查,我已经有足够把握定位根因了:Tailscale启动后,通过MagicDNS接管的解析环节,干扰了OpenClaw业务网关对外部LLM服务商域名的访问。修复思路也就清楚了。
4. 三种解决方案与落地操作
4.1 方案A:让Tailscale回归组网本位(推荐)
这个方案的核心思路是:Tailscale只负责私网组网,不要让它干涉公网流量和DNS解析。适用于绝大多数只需要远程管理内网设备、不需要把服务器当作公网出口的用户。操作非常简单,重新执行一次启动命令,明确关闭MagicDNS对域名解析的接管:
tailscale up --accept-dns=false然后检查两个关键点:第一,/etc/resolv.conf里的nameserver应该恢复正常,不再是100.100.100.100;第二,ip route show里的默认路由应该继续走物理网关。如果这两点都满足,再把OpenClaw服务重启一下:
systemctl restart openclaw # 或者如果你是Docker部署: docker compose restart openclaw重启后再用前面那组curl命令验证,LLM服务商域名应该全部恢复正常。这个方案是我最终采用的,好处是干净利落:Tailscale的远程组网能力继续保留,但不再“好心办坏事”去接管公网解析。如果你远程管理服务器时有需求,也推荐用tailscale ssh这类面向管理通道的功能,而不是把整台服务器变成全局出口。组网归组网、公网归公网,两者不混在一起,问题自然消失。
4.2 方案B:止血式调整:DNS、MTU与超时参数
有些场景比较特殊,比如你的服务器确实需要对某些内网服务开启子网路由,没法直接把DNS相关的接管全部关掉。这种时候可以考虑止血式调整,不改变拓扑,只调整参数。
首先是DNS方面,如果MagicDNS还需要用,可以在系统层面恢复resolv.conf指向公共DNS服务,只在Tailscale内部域名解析时才走它。具体做法取决于你的系统,CentOS系通常在/etc/resolv.conf里恢复,Ubuntu系则看systemd-resolved的配置。同时在OpenClaw这边,把LLM服务商域名加入“直连名单”,让这部分域名不经过虚拟链路的解析流程。不同版本的OpenClaw配置项名称可能不一样,但思路是一致的:公网LLM服务商的域名必须走系统正常解析。
其次是MTU方面,如果你遇到的是大请求必超时,可以在Tailscale启动时调整MTU试一下:
tailscale up --mtu=1400调高MTU可以减少分片几率,但要注意路径上所有设备都要支持这个值,否则反而会出问题。相对稳妥的做法是先小步调,观察一段时间再决定。
最后是超时参数。OpenClaw业务网关的LLM调用超时时间如果设置得太短,比如20秒、30秒,在本来就受影响的链路上几乎是必超时。这个参数通常可以在配置文件中调整,建议放宽到120秒甚至180秒。注意这不是治本,但能明显降低误报率,给排查争取时间。
4.3 方案C:策略路由精准分流(进阶)
如果你的服务器既要作为Tailscale子网路由器,又必须保证对外部LLM服务商的请求始终走物理网络,方案A不适用,方案B又不彻底,那就只能上策略路由。思路是让发往特定目标地址的流量走专用的路由表,绕过虚拟链路。
大致的做法是这样:先创建一张独立路由表,将默认路由指向物理网关,然后用iptables给目标地址打标记,再用ip rule让打了标记的流量走这张表。命令示例如下:
echo "100 llm_direct" >> /etc/iproute2/rt_tables ip route add default via 192.168.1.1 dev eth0 table llm_direct iptables -t mangle -A OUTPUT -d <LLM_API_IP_SEGMENT> -j MARK --set-mark 1 ip rule add fwmark 1 table llm_direct这里<LLM_API_IP_SEGMENT>需要替换成LLM服务商API实际使用的IP段,而且要定期更新,因为各家服务商的IP可能变动,更工程化的做法是用IPset定期同步。这套方案对网络功底有一定要求,普通用户直接抄容易踩坑:IP段过期了没更新,LLM又超时;或者ip rule顺序写错,其他流量也被带偏。我的建议是,除非你的网络环境复杂到必须这么搞,否则优先用方案A,省心可靠。
4.4 验证清单与回滚方法
方案实施完,需要按下面这份清单确认效果,缺一不可:
- 用curl重测几个主要LLM服务商域名,全部在超时时间内返回状态码;
- 在OpenClaw里发一条真实消息,触发一次完整LLM调用,观察业务网关日志,确认不再出现timed out;
- 执行tailscale status,确认这台机器的角色符合预期,没有意外变成全局出口;
- 持续观察15分钟以上,确认不是“刚重启完的两分钟蜜月期”,而是真正恢复。
回滚方法同样重要。排查之前,我建议先备份系统的网络基线,这是一劳永逸的防御动作:
ip route save > routes.bak iptables-save > iptables.bak cp /etc/resolv.conf resolv.conf.bak如果修改之后发现其他服务反而异常了,直接恢复这些备份,再重启网络服务即可。我处理网络问题有个习惯:动手修复前先留后路。尤其是Tailscale这类会主动改动网络栈的工具,出问题时“恢复现场”比“继续调试”快得多。
5. 常见问题速查表与避坑经验
5.1 故障速查表:看现象定位原因
这波复盘之后,我整理了一张速查表,下次再遇到类似问题可以按图索骥:
| 现象特征 | 最可能原因 | 快速判断方法 |
|---|---|---|
| 所有公网请求都超时,SSH正常 | 默认路由被出口节点接管 | ip route show,看default dev是否是tailscale0 |
| 小请求正常,大请求超时 | MTU分片黑洞 | 发大POST测试,看tailscale0的MTU值 |
| 域名解析缓慢或失败 | MagicDNS接管了DNS | cat /etc/resolv.conf,看nameserver是否100.100.100.100 |
| 宿主机curl正常,容器内超时 | Docker NAT与Tailscale规则冲突 | docker exec进入容器再curl对比 |
| 偶发超时,重启后短暂恢复 | 业务网关超时时间设置过短 | 查看OpenClaw配置里的LLM超时参数 |
| 返回401 unauthorized | API Key错误,不是超时 | 检查请求头携带的Key,和超时问题分开看 |
一张表说清楚,排查的时候先对照现象定位原因,不要一上来就拆OpenClaw配置文件。顺带提醒一个常见混淆:热词里经常出现的401 unauthorized和400 context length,这两个是API调用时的身份认证或参数问题,和LLM request timed out完全不是一个层面的故障。超时是“请求没送达或没返回”,401是“请求送达了但权限不够”,排查思路完全不同,混在一起只会浪费时间。
5.2 避坑笔记:四次实战总结的经验
第一次踩坑时,我也犯过“在OpenClaw配置里反复折腾”的错,后来总结出下面几条,每条都是用教训换来的。
第一,装任何网络层工具之前,先做一次网络基线快照。路由表、resolv.conf、iptables规则,三个命令顶多花一分钟,关键时刻能救命。第二,不要在服务器上随手开启全局出口。Tailscale这类组网工具,绝大多数使用场景只需要私网连接,不需要把流量全部引入虚拟链路。第三,排查顺序严格按“网络变更时间点、路由与DNS、MTU、应用配置”来。我在OpenClaw场景里犯过的最大错误,就是先怀疑API Key和模型配置,结果空转了大半天。第四,多留意错误日志里的细节。比如session file locked这类错误,常被当成独立故障,其实是LLM超时后的连锁反应。看到它,反而要回头关注底层网络。
5.3 遇到同类故障时的第一诊断动作
最后分享一个成本最低、信息量最大的“第一诊断动作”:遇到OpenClaw突然大面积LLM超时,先执行tailscale down,等五秒钟,再随便发一条消息试试。如果业务通道立刻恢复,不用怀疑,问题就在Tailscale的网络栈改动上;如果停掉后还是超时,再回到OpenClaw日志和外部API连通性去查。这个动作我后来几乎每次都先做,因为它能在十秒内把范围从“全链路”缩小到“一个网络层变更点”。
回到这次故障本身,我最终用的方案就是方案A:重新执行tailscale up --accept-dns=false,让DNS解析回归系统正常路径,然后重启OpenClaw。后续观察了整整一天,再没有出现LLM request timed out,远程管理内网设备的功能也完好如初。
我个人在实际操作中的体会是,OpenClaw这类Agent服务对公网LLM API的依赖度非常高,任何一点网络波动都会被放大成“服务不可用”。而Tailscale这类组网工具为了达成“零配置组网”,确实会倾向接管网络栈,两者相遇时,冲突几乎是必然的。所以我的习惯是:动网络层之前先备份基线,出问题后先用停用五分钟做诊断,修复时则坚持“组网归组网、公网归公网”的原则,让每一条流量走它该走的路。这个思路不仅限于Tailscale,对任何会修改路由、DNS、防火墙的组网工具都适用。希望这篇笔记能帮到正在被LLM request timed out折磨的人。