每次滚动发布都有几分钟大量 502、半夜还莫名其妙被重启,我查到底才发现是 K8s 的就绪探针没配、存活探针又配得太敏感:一次健康检查探针配置失当、把自愈机制配成故障源的深度复盘

我们的服务跑在 K8s 上,出了两个看似不相关的问题:每次滚动发布都有几分钟接口大量报 502/连接被拒,以及有些 Pod 半夜莫名被 Killed 重启(没崩溃没 OOM)。查到底发现根因都在健康检查探针,且是两个相反方向的错:一是没配 readiness 探针,K8s 不知道 Pod 何时就绪、容器一启动就把流量打进来而应用还没就绪所以 502;二是 liveness 探针配得太敏感(timeout 1s、failureThreshold 1),健康但偶尔 Full GC 慢一下的 Pod 被误判为死、被杀掉重启。这篇复盘从故障现场讲到 readiness/liveness/startup 三个探针各自的职责(readiness 管摘流量不重启、liveness 管重启、startup 保护慢启动),再到配好 readiness、放宽 liveness 且只查自身绝不查外部依赖否则雪崩、慢启动加 startup 的完整正解,以及按故障性质分级匹配力度处置、对自动化保护机制的误判后果保持敬畏、拆解笼统概念辨明内部职责的认知。

每次滚动发布都有几分钟大量 502、半夜还莫名其妙被重启,我查到底才发现是 K8s 的就绪探针没配、存活探针又配得太敏感:一次健康检查探针配置失当的深度复盘

那两个问题是发布和监控告警双重暴露的:我们的服务跑在 K8s 上。第一个症状是——每次滚动发布新版本,都会有那么几分钟,接口大量报 502 / 连接被拒,等所有新 Pod 都起来了才恢复;运维一开始以为是"发布期抖动正常"。第二个症状更诡异——有些 Pod 半夜会莫名其妙地被重启,日志里没崩溃、没 OOM,可 kubectl describe 显示它被 Killed 然后 Restarted。我把这两件事一起查到底,才看明白,后背发凉:根因都出在 K8s 的两个健康检查探针配置上,而且是两个方向相反的错:第一,readiness(就绪)探针没配——K8s 不知道一个 Pod"什么时候才准备好接收流量",于是容器进程一启动(但应用还在加载、还没真正就绪)它就把流量打进来了,而此时应用还连不上/还没监听,就报 502/拒绝;第二,liveness(存活)探针配得太敏感——它检查的超时太短、失败阈值太低,结果一个健康但偶尔慢一下(比如在 Full GC、或某次请求略卡)的 Pod,被探针误判为"死了",K8s 就把这个本来好好的 Pod 给杀了重启问题的根,是我没理解 readiness 和 liveness 这两个探针各自的职责:readiness 管"能不能接流量"(没配好就把流量打给没就绪的 Pod),liveness 管"要不要重启"(配太敏感就误杀健康 Pod)。这篇就把这次"健康检查探针配置失当"的坑,从头到尾复盘一遍。

故障现场:没配就绪探针 + 存活探针太敏感

问题在于 readiness 探针缺失(流量打给没就绪的 Pod)和 liveness 探针太敏感(误杀健康 Pod):

# ✗ 出问题的配置: 没有readiness探针, liveness探针又太敏感
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: my-app
        image: my-app:1.2.0
        # ✗ 问题一: 没有配 readinessProbe!
        #    → K8s不知道Pod何时"就绪", 容器进程一起来就往里打流量;
        #    → 但应用可能还在启动(加载配置/连DB/预热), 还没真正能服务 → 502/拒绝。

        # ✗ 问题二: liveness探针配得太敏感
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5     # ✗ 太短! 应用可能要30s才启动完, 5s就开始查 → 启动期就被判死
          periodSeconds: 5
          timeoutSeconds: 1          # ✗ 太短! 一次GC/慢请求就可能超过1s → 误判
          failureThreshold: 1        # ✗ 太低! 失败1次就重启 → 偶尔抖一下就被杀
        # → 结果: 健康但偶尔慢一下(Full GC等)的Pod, 被误判为死, K8s把它杀了重启。

# 现象:
# - 滚动发布时大量502(没readiness, 流量打给还没就绪的新Pod);
# - Pod半夜莫名重启(liveness太敏感, 把GC中/偶尔慢的健康Pod误判为死, 杀掉重启)。

# 两个探针的职责(关键):
# - readinessProbe(就绪探针): 回答"这个Pod现在能接收流量吗?"
#     不通过 → K8s把它从Service的endpoints里【摘掉】(不打流量给它), 但【不重启】它;
#     用途: 启动未完成时、临时过载时, 先别给它流量, 等它就绪/缓过来。
# - livenessProbe(存活探针): 回答"这个Pod是不是死了/卡死了, 需要重启吗?"
#     不通过 → K8s【重启】这个容器;
#     用途: 检测进程死锁/卡死等"重启才能恢复"的情况。

# 关键: 没配readiness → 流量打给没就绪的Pod(502); liveness太敏感 → 误杀健康Pod;
#       两个探针职责不同(readiness管摘流量、liveness管重启), 配错方向相反, 都会出事。

第一次理清"原来是两个探针、一个没配一个太凶"时,我又懊恼又恍然:"我一直以为健康检查就是'配个 /health 让 K8s 探一下'这么笼统的一件事,完全没分清 readiness 和 liveness 是两个职责完全不同的探针。"这个坑最坑的地方在于:两个症状看起来毫不相关(一个是发布期 502、一个是半夜重启),根因却都在探针配置上,且是两个相反方向的错(一个该配的没配、一个配得过激);而且发布期 502 容易被当成"正常抖动"忽略,半夜重启又因为"重启后就好了"而难抓现行下面就来拆解,这两个探针到底各管什么、该怎么配。

第一件事:搞懂 readiness 和 liveness 探针的不同职责

我顺着这次事故,把 K8s 三种探针的职责彻底理清了。

K8s 的健康检查探针: readiness / liveness / startup 各管什么?

【核心: readiness管"能否接流量"(不过就摘流量不重启); liveness管"要否重启"(不过就重启); startup管"启动完没"(保护慢启动); 三者职责不同, 别混用】

1. readinessProbe(就绪探针): "现在能接收流量吗?"
   - 通过 → Pod留在Service的endpoints里, 接收流量;
   - 不通过 → 把Pod从endpoints【摘掉】(停止给它流量), 但【不重启】, 等它恢复;
   - 典型用途: ①启动未完成(还在加载/连DB/预热)时, 别给流量; ②临时过载/依赖不可用时, 暂时摘出去缓一缓。
   - ★没配的后果(本文): 容器一启动就被打流量, 而应用还没就绪 → 502/拒绝。

2. livenessProbe(存活探针): "死了/卡死了吗?需要重启吗?"
   - 通过 → 啥也不做;
   - 不通过(达到failureThreshold) → 【重启容器】;
   - 典型用途: 检测"进程还在但已死锁/卡死、只有重启才能救"的情况;
   - ★配太敏感的后果(本文): 健康但偶尔慢(GC/瞬时卡)的Pod被误判为死, 被无谓重启。

3. startupProbe(启动探针, 慢启动应用必备):
   - 专门保护"启动慢"的应用: startup没通过前, 暂停liveness/readiness检查;
   - → 给应用足够的启动时间, 避免"还没启动完就被liveness判死重启"(陷入重启循环);
   - 慢启动(如JVM应用)强烈建议配。

4. 关键区别: 不过的"后果"完全不同
   - readiness不过 = 摘流量(温和, 不重启, 可恢复);
   - liveness不过 = 重启(激进, 杀进程);
   - → 把"临时不可用(该摘流量)"错配成liveness, 就会把本可自愈的Pod反复重启 → 雪上加霜。

5. 探针参数的含义:
   - initialDelaySeconds: 容器启动后多久开始探(要≥应用启动时间, 否则启动期被探死);
   - periodSeconds: 多久探一次; timeoutSeconds: 单次探测超时(别太短, 留余量);
   - failureThreshold: 连续失败几次才算数(liveness别设1, 容忍偶发抖动); successThreshold。

一句话: readiness管"能否接流量"(不过摘流量不重启)、liveness管"要否重启"(不过重启)、startup保护慢启动;
   没配readiness会把流量打给没就绪的Pod(502), liveness太敏感会误杀健康Pod; 三探针职责不同, 要按职责正确配。

这套认知,是整个坑的根。readinessProbe(就绪探针):"现在能接收流量吗?"——不通过就把 Pod 从 Service endpoints 摘掉(停止给流量)但不重启,等它恢复;没配的后果就是容器一启动就被打流量、应用还没就绪→502livenessProbe(存活探针):"死了/卡死了吗?要重启吗?"——不通过就重启容器;配太敏感就把健康但偶尔慢的 Pod 误判为死、无谓重启startupProbe(启动探针):保护慢启动应用,startup 没通过前暂停 liveness/readiness,避免还没启动完就被判死重启(JVM 应用必备)。关键区别:readiness 不过=摘流量(温和、可恢复),liveness 不过=重启(激进);把临时不可用错配成 liveness 就会反复重启本可自愈的 Pod。参数:initialDelaySeconds 要≥应用启动时间、timeoutSeconds 别太短、liveness 的 failureThreshold 别设 1。一句话:readiness 管"能否接流量"(不过摘流量不重启)、liveness 管"要否重启"(不过重启)、startup 保护慢启动;没配 readiness 会把流量打给没就绪的 Pod,liveness 太敏感会误杀健康 Pod;三探针职责不同,要按职责正确配。

第二件事:正解——配好 readiness、放宽 liveness、慢启动加 startup

搞懂了原理,正解就清晰了:配上 readiness 探针(应用真正就绪才接流量)、把 liveness 探针放宽(容忍偶发抖动、别误杀)、慢启动应用加 startup 探针、readiness 和 liveness 用不同的检查端点

# ====== 正解: readiness配上 + liveness放宽 + startup保护慢启动 ======
spec:
  template:
    spec:
      containers:
      - name: my-app
        image: my-app:1.2.0

        # ★ startup探针: 保护慢启动(给最多 30*10=300s 启动时间)
        startupProbe:
          httpGet: { path: /health/live, port: 8080 }
          periodSeconds: 10
          failureThreshold: 30        # startup通过前, 不跑liveness/readiness → 启动期不会被误杀

        # ★ readiness探针: 应用"真正就绪"(依赖就绪、能服务)才接流量
        readinessProbe:
          httpGet: { path: /health/ready, port: 8080 }  # ready端点: 检查DB/缓存等依赖是否就绪
          initialDelaySeconds: 0       # 有startup保护, 这里可以0
          periodSeconds: 5
          timeoutSeconds: 2
          failureThreshold: 3          # 连续3次不就绪才摘流量(不重启)
          successThreshold: 1
        # → 没就绪/临时过载时, 摘掉流量不打给它(但不重启), 恢复了再加回来 → 发布期不再502。

        # ★ liveness探针: 放宽, 只在"真的卡死"时才重启
        livenessProbe:
          httpGet: { path: /health/live, port: 8080 }   # live端点: 只检查进程本身是否卡死(别查外部依赖!)
          periodSeconds: 10
          timeoutSeconds: 3            # 给足余量, 别一次GC就超时
          failureThreshold: 3          # 连续3次失败(约30s)才重启, 容忍偶发抖动
        # → 只有"真的卡死了"才重启, 不再误杀偶尔慢一下的健康Pod。
# ====== 配置要点 ======
# 1. readiness 和 liveness 用【不同的检查逻辑/端点】:
#    - readiness(/health/ready): 检查"能否对外服务", 可包含关键依赖(DB/缓存)是否就绪;
#    - liveness(/health/live): 只检查"进程自身是否卡死", 【不要】查外部依赖!
#      → 否则: DB抖一下, liveness挂了, K8s把你所有Pod重启(把"依赖问题"升级成"全部重启"灾难)。
# 2. liveness要"宽容": timeoutSeconds留余量、failureThreshold别设1(容忍GC/瞬时卡), initialDelay够长或用startup;
# 3. readiness可"敏感些": 它不过只是摘流量(温和), 用于过载保护/依赖未就绪时暂时退出;
# 4. 慢启动应用(JVM等)用startupProbe保护启动期, 避免重启循环(CrashLoopBackOff);
# 5. 配合优雅停机(同356篇): 关闭时先readiness不就绪→摘流量→处理完存量→退出。

# ====== 一个最关键的反模式 ======
# ✗ liveness探针检查了外部依赖(DB/下游): 依赖一抖, 所有Pod的liveness都挂 → 全部被重启 → 雪崩!
#   → liveness只查自己"活没活", 依赖问题交给readiness(摘流量)和熔断, 而不是重启。

# 核心: readiness配好(就绪才接流量, 发布不502)、liveness放宽且只查自身(别查依赖, 别误杀)、
#   慢启动加startup; 分清"摘流量(readiness)"和"重启(liveness)"两种处置, 按职责配对探针。

修复的核心,是"配好 readiness、放宽 liveness 且只查自身、慢启动加 startup"正解:startup 保护慢启动(通过前不跑 liveness/readiness,启动期不被误杀)、readiness 应用真正就绪(依赖就绪)才接流量(没就绪只摘流量不重启,发布期不再 502)、liveness 放宽(timeout 留余量、failureThreshold 别设 1,只在真卡死时重启)。配置要点:readiness 和 liveness 用不同端点/逻辑——readiness 可查关键依赖,liveness 只查进程自身、绝不查外部依赖(否则 DB 一抖所有 Pod 被重启、雪崩)最关键的反模式:liveness 检查外部依赖→依赖一抖所有 Pod 被重启→雪崩;liveness 只查自己活没活,依赖问题交给 readiness 和熔断归根结底:readiness 配好(就绪才接流量,发布不 502)、liveness 放宽且只查自身(别查依赖、别误杀)、慢启动加 startup;分清"摘流量(readiness)"和"重启(liveness)"两种处置,按职责配对探针。

第三件事:K8s 部署与健康检查的其他常见坑

排查后我把 K8s 部署、健康检查相关的其他坑也系统梳理了一遍。

K8s 部署与健康检查的其他常见坑

# 1. 探针职责配错(本文): 没readiness→502, liveness太敏感→误杀。→ 按职责正确配。

# 2. liveness查外部依赖: 依赖抖动→所有Pod重启→雪崩。→ liveness只查自身。

# 3. 慢启动没startup探针: 启动慢被liveness判死, 陷入CrashLoopBackOff。→ 配startupProbe。

# 4. 没配资源requests/limits: 调度不合理/被OOMKilled或挤占。→ 合理设requests/limits。

# 5. 优雅停机没做(同356篇): 滚动更新时正在处理的请求被强杀。→ readiness先摘流量+preStop+SIGTERM处理。

# 6. 镜像用:latest(同344篇): 不可复现/拉到意外版本。→ 用确定的版本tag/digest。

# 7. 副本数为1/无PodDisruptionBudget: 单点, 更新/驱逐时短暂全不可用。→ 多副本+PDB。

# 8. 配置/密钥硬编码进镜像: 不安全、改配置要重新打镜像。→ ConfigMap/Secret注入。

# 共同根源: K8s把"如何判断服务健康、如何调度、如何更新"交给了一堆【声明式配置】;
#   这些配置每一项都有明确语义和后果, 不理解语义就按感觉填(或不填), 就会让K8s做出你没预期的动作。

# 核心: 用K8s, 要理解每个配置项(探针/资源/更新策略)的【确切语义和它触发K8s做什么】;
#   尤其是探针——分清readiness(摘流量)和liveness(重启)的职责, 按职责配, 别让健康检查本身成为故障源。

排查让我把 K8s 部署与健康检查的其他坑也梳理清了。一、探针职责配错(本文)。二、liveness 查外部依赖→雪崩三、慢启动没 startup→CrashLoopBackOff四、没配 requests/limits五、优雅停机没做六、镜像用 :latest七、副本数为 1/无 PDB八、配置/密钥硬编码它们的共同根源是:K8s 把"如何判断服务健康、如何调度、如何更新"交给了一堆声明式配置;这些配置每一项都有明确语义和后果,不理解语义就按感觉填(或不填),就会让 K8s 做出你没预期的动作核心是:用 K8s,要理解每个配置项(探针/资源/更新策略)的确切语义和它触发 K8s 做什么;尤其是探针——分清 readiness(摘流量)和 liveness(重启)的职责,按职责配,别让健康检查本身成为故障源下面这张图,是这次探针配置坑的成因与解法:

第四件事:readiness vs liveness 探针对比表

这次踩坑后,我把 readiness 和 liveness 两个探针的职责对比成一张表,贴在了部署清单的注释里。

维度 readinessProbe(就绪) livenessProbe(存活)
回答的问题 能接收流量吗? 死了/卡死要重启吗?
不通过的后果 从 Service 摘掉(停流量) 重启容器
是否重启 否(温和, 可自愈) 是(激进)
能否查外部依赖 可以(依赖未就绪先摘流量) ✗ 绝不(否则雪崩)
敏感度 可敏感些(只摘流量) 要宽容(别误杀)
没配的后果 流量打给没就绪 Pod(502) 卡死的 Pod 不会被重启自愈

这张表把两个探针钉清了。核心是:这俩探针最本质的区别,是"不通过时的处置不同"——readiness 不通过是"暂时别给它活干(摘流量)"(温和、可逆、能自愈);liveness 不通过是"它没救了, 重启吧"(激进、杀进程);一个对应"临时不可用"(等等就好),一个对应"彻底卡死"(只能重启)——把这两种状态和处置对应错,就会出大问题它给我的最大启发是:对一个"不健康"的事物,处置方式不该只有一种,而要根据"不健康的程度/性质"分级处置——"临时性的、可自愈的不健康"该用温和手段(隔离、限流、等待),"永久性的、需干预才能恢复的不健康"才该用激进手段(重启、替换);用"重启"(核武器)去对待一个"临时慢一下"(感冒)的 Pod,是杀鸡用牛刀且会误伤;反之,对真卡死的 Pod 只摘流量不重启,它永远好不了这给了我一种处理"异常/降级"的清醒:设计任何"故障处置/自愈机制"时,要先区分故障的不同性质(临时 vs 永久、可自愈 vs 需干预),再为每种性质匹配恰当力度的处置——而不是"一有问题就用最重的手段(重启/熔断/全部下线)";"按故障性质分级、用匹配力度的手段处置",是构建一个既能自愈、又不会反应过激自伤的健壮系统的关键认清 readiness 摘流量与 liveness 重启的处置之别、按故障性质分级匹配力度处置——是这个坑带给我的认知。

第五件事:这次事故暴露的"自愈机制本身成了故障源"

这次让我反思更深一层:那个本该"保障健康"的健康检查,反而成了"制造故障"的元凶。我把"配置不当的健康检查"和"配置得当的健康检查"对比成表。

维度 配置不当(本文) 配置得当
liveness 查依赖 依赖抖动→全部 Pod 重启→雪崩 只查自身, 依赖问题摘流量
liveness 太敏感 误杀健康 Pod 容忍抖动, 真卡死才重启
没 readiness 流量打给没就绪 Pod(502) 就绪才接流量
角色 健康检查成了故障放大器 健康检查保障稳定
本质 保护机制反噬 保护机制尽责

这张表道出了最深刻的教训。核心是:健康检查的本意,是"保障服务健康、自动剔除/恢复故障实例"——可一旦配置不当,它反而成了故障的制造者和放大器:误杀健康 Pod、把依赖抖动放大成全体重启的雪崩;那个"守护者",因为配置失当,亲手制造了它本该防范的灾难它给我的深刻启发是:任何"自动化的保护/自愈/容错机制"(健康检查、自动重启、自动扩缩容、熔断、自动故障转移),都是一把双刃剑——配置得当,它保护系统;配置不当或考虑不周,它自己就会成为故障源,甚至比它要防范的问题更危险;因为它手握"自动采取激烈行动(重启、下线、切换)"的权力,一旦它的判断错了,就会"自动地、大规模地"造成破坏这给了我一种对待自动化机制的敬畏:引入任何"会自动采取激烈动作"的机制时,要格外审慎地设计它的"触发条件",并问"如果它误判了, 会造成多大破坏?它会不会把小问题放大成大灾难?"——给它足够的"容错余量"(别太敏感)、限制它的"动作范围/速率"(别一次全干)、想清它和其他机制的相互作用(别和依赖故障形成正反馈雪崩);"对自动化保护机制的误判后果保持敬畏、审慎设计其触发与影响范围",是避免'守护者反成杀手'的关键认清自愈机制配错会反噬成故障源、对自动激烈动作的误判后果保持敬畏——是这个探针坑带给我的工程态度。

第六件事:配 K8s 探针时,我现在的自检习惯

现在每当我要给一个服务配 K8s 健康检查探针,我都会先按这张图问自己:

这张图的精髓,是"readiness 管接流量、liveness 只查自身且宽容、慢启动加 startup"先配 readiness就绪才接流量、慢启动加 startup、liveness只查自身且别太敏感,绝不让 liveness 查外部依赖这套习惯,让我从"笼统配个 /health 探针"变成了"分清 readiness/liveness/startup 各自职责按需配"——核心始终是:readiness 管摘流量(就绪才接流量)、liveness 管重启(只查自身、要宽容、别查依赖)、慢启动用 startup 保护,别让健康检查本身成为故障源。

我立下的几条规矩

这场"发布期 502、健康 Pod 被误杀重启"的事故,换来了我配 K8s 健康检查时,刻进骨子里的几条铁律:

  1. readiness 管"能否接流量",不过只摘流量不重启。没配它流量会打给没就绪的 Pod(502)。
  2. liveness 管"要不要重启",不过就重启容器。配太敏感会误杀健康 Pod。
  3. liveness 绝不检查外部依赖。否则 DB 一抖所有 Pod 被重启、雪崩。
  4. liveness 要宽容:timeout 留余量、failureThreshold 别设 1。容忍 GC/偶发抖动。
  5. 慢启动应用(JVM 等)配 startupProbe。避免启动期被判死、陷入 CrashLoopBackOff。
  6. readiness 和 liveness 用不同端点和检查逻辑。职责不同,别混用一个。
  7. 自动化保护机制是双刃剑,审慎设计触发条件和影响范围。别让守护者反成杀手。

写在最后

回头看,这场由"健康检查探针配置失当"引发的、发布 502 加无故重启的事故,真正教给我的,远不止"配好 readiness、放宽 liveness"这一个技巧。它让我对"一个'笼统的概念'(健康检查), 背后往往是几个'职责截然不同的具体角色'(就绪 vs 存活); 把它们笼统地看成一回事、混为一谈, 就会用错",有了一次刻骨的体会。我栽跟头,是因为在我脑子里,"健康检查"就是笼统的一件事——"让 K8s 探一下我的服务还活着不"。我没有意识到,K8s 把这件"笼统的事"精心地拆成了两个(其实三个)职责完全不同的角色:一个管"现在能不能接客(readiness)",一个管"是不是已经病死了要重新投胎(liveness)";这两个角色,"判断的标准不同"、"判断错了的后果也截然不同"(一个摘流量、一个重启);而我用一个笼统的理解去对待它们,该配的(readiness)没配、该温柔的(liveness)又太凶,两头都错这让我领悟到一个关于"笼统概念与具体职责"的深刻认知:很多我们习以为常的"笼统概念"(健康检查、缓存、超时、权限、日志……),在深入之后,往往会分化成几个职责不同、需要分别对待的具体维度;"把一个笼统概念当成单一的、铁板一块的东西",是误用它的常见根源——因为你会用"一套笼统的处理"去对待本应"分别精确处理"的不同维度;真正的掌握, 始于"把笼统的概念, 拆解成它内部那些职责分明的具体部分"这给了我一种学习和使用任何概念时的深度:面对一个"用着熟、但其实没细究过"的概念时,要主动去问:"这个笼统的东西, 内部是不是其实分了好几种、各管各的?它们的区别和各自的正确用法是什么?"——把"一个模糊的整体"拆解成"若干清晰的、职责分明的部分";"拆解笼统概念、辨明其内部各部分的不同职责",是从'会用个大概'走向'精确驾驭'的关键一步认清笼统概念背后是职责分明的具体角色、拆解概念辨明各部分职责再精确使用——这,是我用一次探针配置失当的事故,换来的、关于 K8s、也关于如何深入理解一个概念的、最朴素也最深刻的领悟。如果这篇复盘,能让你下次配 K8s 探针时,先停下来分清 readiness 和 liveness 各管什么、别让 liveness 去查数据库,那我对着那发布期的 502 和半夜的重启告警排查的这段时间,就值了。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

调用下游服务的接口慢得离谱、机器上还堆了几万个 TIME_WAIT,我抓包才发现每发一个请求都在重新三次握手加 TLS 握手:一次 HTTP 连接没复用、每次新建连接把建连开销付了无数遍的深度复盘

2026-6-2 20:22:28

技术教程

同一句话调用大模型做意图分类,有时分对、有时分错,复现 bug 时还死活复现不出来,我查到底才发现是 temperature 把随机性引了进来:一次 LLM 采样参数设置不当、把概率组件当确定性函数用的深度复盘

2026-6-2 20:32:50

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索