- 博客(1430)
- 收藏
- 关注
原创 批量更新中间失败,为什么“捕获异常继续”可能改变回滚结果?
批量导入十条记录,第六条不符合规则。业务希望返回一份失败清单,于是在事务方法内部捕获异常,继续处理后面几条。最终接口显示“部分失败”,数据库却提交了前面已经执行的更新。这不一定是事务失效,而是代码已经改变了异常传播和事务粒度。要讨论回滚,先明确这一批是整体成功,还是允许每条独立成功。本文用合成记录和 SQLite 验证整批回滚与逐项保存点的差别,没有运行 Spring 容器、JDBC批处理或生产数据库锁测试。
2026-11-02 12:42:11
335
原创 把外部接口藏到适配层后,怎样确认业务返回没有悄悄变?
订单查询原来直接返回供应商DTO。后来准备换接口,业务代码里到处是外部状态码和字段名。加一层适配器可以减少这种耦合,但如果顺便改变空值、错误和状态含义,调用方仍会受到影响。适配层要承担协议差异,不是把外部对象换个类名再传进去。先固定业务端真正依赖的契约,才能判断这次拆分是否保持行为一致。本文使用合成供应商响应,在Java12.0.1中验证状态和缺失结果映射,没有真实HTTP、Spring客户端或供应商API调用。
2026-11-02 12:40:57
364
原创 异步任务的日志串错请求,先分清请求标识和任务标识
假设入口请求建立了requestId,并派生“查工单”“查客户”两个子任务。两个任务继承同一个请求标识,但各自拥有不同任务标识。完成顺序改变时,这个关系也不改变。字段本例含义不能代替什么requestId本服务一次入口处理用户身份或授权凭证taskId某个子任务整个业务操作的幂等键跨重试的业务操作关联每次传输请求的唯一记录traceId分布式链路关联自动保证所有日志完整这些名称需要团队统一,不是说每个系统必须同时拥有四个字段。
2026-11-02 12:39:43
296
原创 数据库连接等不到,怎样把“等待超时”变成明确的接口行为?
接口已经通过线程池接收任务,却迟迟拿不到数据库连接。调用方最后看到超时,工作线程仍在等待。把线程数继续加大,可能只会让更多线程挤在连接池门口。连接池是另一层容量边界。任务被接收,不代表数据库资源已经可用;获取连接也不能无限等待,应该受到剩余请求预算约束。本文用 Java Semaphore 模拟单个稀缺资源的等待与释放,帮助检查控制流。它不是真实数据库连接池测试,没有测SQL、锁等待或生产吞吐。
2026-11-02 12:38:35
372
原创 只缓存了十几个字节,为什么大缓冲区仍可能被一起保留?
解析一块数据后,只想缓存其中很短的头部。代码对 ByteBuffer 做了一次切片,缓存里看到的剩余字节很少,原来的大数组却可能仍然通过这份视图被引用。这里的关键不是切片长度,而是切片是否复制了数据。共享视图可以减少复制,也会让生命周期相互关联。排查缓冲区滞留时,需要把“可见范围”和“底层存储”分开看。本文只验证Java堆内ByteBuffer切片的共享关系,没有采集生产堆转储,也不讨论某个网络框架的引用计数协议。
2026-11-02 12:37:25
277
原创 给订单列表拆一个查询模型,怎样确认接口行为没有变?
订单列表只需要编号、金额和状态,服务却先加载一个包含多种关联的业务实体,再逐项转成返回对象。想减少这层依赖,可以引入专门的查询模型,但“字段看起来一样”还不够证明接口行为一致。排序、空值、金额精度、分页边界和权限过滤,都可能在拆分时改变。先把这些外部行为固定下来,再替换内部查询路径,改动才容易审查。本文采用合成订单数据,在本机 Java 12.0.1 中对照两条映射路径。没有运行 Spring Data JPA、真实 SQL、浏览器或生产性能测试。
2026-11-01 19:50:58
646
原创 数据库提交前还是提交后发消息?先把事务时间线画清楚
订单写入数据库后,需要通知另一个服务。把消息发送放进带的方法,看起来像是“一起成功,一起失败”。但数据库和消息系统通常各自提交,Java 方法上的本地事务不会自动把它们变成一个原子操作。这次只讨论消息发送时机。示例采用合成订单与内存 SQLite,验证本地事务与发件箱的状态变化;没有真实消息代理、Spring 容器或生产数据库测试。
2026-11-01 19:49:47
582
原创 租户参数进了线程池,为什么不能继续信任 ThreadLocal?
请求线程已经识别出当前租户 A,业务把查询任务交给线程池。任务里再读一次,却得到空值。有人于是改用可继承上下文,希望线程自动带过去;结果线程池复用后,问题变得更隐蔽。关键区别是:任务提交发生在某次请求里,执行线程却不属于这次请求。要跨越这个边界,应该传递一份经过确认的范围,而不是假设工作线程里自然存在正确身份。本文用单线程复用的最小模型检查传递与清理,不把模拟结果当成真实 Spring 请求链验证。没有生产环境测试,也不涉及真实租户数据。
2026-11-01 19:48:36
681
原创 批处理限制了线程数,为什么调用方仍然不知道任务有没有被接收?
一个批处理接口收到文件后,把解析任务放进线程池,立即返回“提交成功”。高峰时线程池拒绝新任务,异常被统一日志捕获,接口仍然返回成功。调用方等不到结果,也不知道该不该重试。限制并发只是资源规则。对外还需要一份接收契约:什么时候算接收成功,什么时候明确拒绝,已经接收的任务怎样查询结果。否则系统保护住了线程,却把不确定性交给了调用方。本文用 Java 本地有界执行器验证接收与拒绝,没有真实文件上传、数据库连接池或生产压测。
2026-11-01 19:47:23
620
原创 JVM 已加载类数量一直增加,就能判断类加载器泄漏吗?
监控里“已加载类总数”不断上升,很容易让人联想到类加载器泄漏。但这个指标如果指的是 JVM 启动以来累计加载的类,本来就不会因为类卸载而下降。排查前先确认看的是累计值还是当前值。把两者混在一起,再对着一条上升线讨论泄漏,结论会从起点就偏离。本文在本机 Java 12.0.1 进程里读取类加载管理指标,并用可控代理类加载补充观察。没有生产堆转储,也没有证明或制造一个真实类加载器泄漏案例。
2026-11-01 19:46:06
751
原创 AI 咨询后的成交额,不等于 AI 创造的收入:先扣退款和重复归因
同一笔订单被三个会话关联,每个会话大盘都记全额 GMV,汇总时就会膨胀三倍。再把退款漏掉,把模型 Token 费当成全部成本,很容易算出一个足够惊人的“ROI”。这些问题首先是账本口径问题。
2026-10-31 23:06:48
583
原创 模型停用预告不能只转到群里:把公告变成路由迁移清单
供应商公告了停用日,网关配置里却还留着旧模型,通常不是大家没看过消息,而是消息没有变成可查询的依赖清单:哪些业务在用、备用模型是否验证、谁负责迁移,以及到期后怎样阻止继续调用。
2026-10-31 23:05:42
665
原创 跨模型重试最危险的空档:动作已执行,结果却还没记下来
模型 A 调用退款工具,服务端执行成功,但响应在网络中断了。模型 B 接手后又生成一条退款工具调用。两条模型调用标识不同,业务动作却是同一个。若只按模型返回的 callId 去重,就可能再次退款。
2026-10-31 23:04:35
648
原创 洪峰演练先做守恒检查:到达的请求,最后都去了哪里?
队列满了以后直接return,吞吐日志可能看起来仍然稳定。但调用方还在等,接收计数和完成计数也对不上。讨论峰值容量之前,先确认每个请求都有去处:运行、排队、完成,或者明确拒绝。
2026-10-31 23:03:29
635
原创 演练报告少写一句“全程无损”,多留三条复核路径
一份演练报告最有用的部分,通常不是“系统稳如磐石”,而是别人能否重放条件并核对结论。用了什么输入,运行在哪个环境,哪些断言通过,哪些链路根本没有执行,这些信息决定结论能传播到哪里。
2026-10-31 23:02:17
626
原创 九道防线一起上,为什么还需要一份失败处置表?
鉴权拒绝一次,重试器把它重试;排队超时一次,降级器又把它放回原队列;计量失败一次,路由器重新发模型请求。每层都在“自愈”,组合起来却可能把已经应该结束的请求重新唤醒。
2026-10-30 13:18:06
585
原创 大模型网关总装配:缓存再快,也不能排在授权检查前面
授权与适用的预算检查放在内容返回和外部动作之前。缓存命中后,可以按缓存的真实费用口径记录;不必假装它产生了模型推理费,但也不能让这类业务请求完全不留痕。Agent 护栏与审批文档对执行前检查的划分,可以帮助区分输入、输出和工具动作的责任。下面用事件列表观察执行顺序,不假装接入了某个完整网关框架。if(!if(!if(!if(!=0 ||!保存为Demo.java,执行java Demo。
2026-10-30 13:15:53
695
原创 自动恢复不能无限重试:给请求状态机一个真正的终点
超时线程宣布失败,备用请求稍后返回成功,客户端又发来取消。若三个回调分别往响应、计量和连接池里写状态,同一个请求就可能被重复结算,或者明明已经取消还继续向页面输出。
2026-10-30 13:13:52
660
原创 AI 短剧后端先别急着排镜头:重复回调会不会让任务状态倒退?
一个短剧项目可以拆成多段视频任务。提交成功后,渲染还没结束;页面等到“完成”回调后开始取文件,稍后又收到一条旧的“处理中”状态。若消费者照单覆盖,已完成镜头就会重新变成进度条。
2026-10-30 13:11:16
357
原创 发布前再核对一次:批准的是哪一份字节,回退又由谁执行?
评审通过的包和实际发布的包若不是同一份,审批记录就无法证明发布对象已被检查。配置临时改了一行、依赖偷偷换了一版,都可能让“昨天已经测过”失去指向。
2026-10-30 13:09:44
665
原创 路由算法开始探索之前,先把不健康的供应商排除
从轮询升级成自适应路由,很容易让人把注意力放在“算法是否聪明”。但一个更基础的反例是:随机探索抽中了已熔断的供应商,或者选择了不支持工具调用的模型。奖励函数再复杂,也不应该替这些硬约束开后门。
2026-10-29 22:26:08
616
原创 ByteBuffer.slice 少复制了一份数据,为什么还不能叫网络零拷贝?
把byte[]包进 ByteBuffer,再切出一个视图,的确可以共享已有内容。但网络发送还可能经过编码、TLS、用户态缓冲与内核路径。只看到没有调用,不足以说明整个发送过程都没有复制。
2026-10-29 22:24:39
631
原创 预售库存演练:重试可以重放结果,不能再减一次库存
AI 导购可以推荐商品、解释活动规则,但它看到的库存快照不能成为最终扣减依据。一次下单超时后,用户重试、网关重试、模型又调用一次工具,若每条路径都减一次库存,边缘缓存再快也挡不住账实不符。
2026-10-29 22:23:00
644
原创 99.99% 可用率怎么来的?先问重试、降级和取消有没有进分母
主模型失败,备用模型成功,日志里出现两次尝试:算一次请求还是两次?返回了离线 FAQ,但没回答用户原来的库存问题:算成功还是降级?这些口径不说清楚,漂亮的小数点后四位很容易只是统计方式变了。
2026-10-29 22:21:38
680
原创 “这个月省了千万”先别写:把用量变化、单价变化和预测拆开
缓存命中率升了,竞价节点便宜了,月中账单也低了,能不能直接相加得到月度节省?不能。同一批请求可能同时享受缓存和调度优化;业务量下降也会让账单变少,却不一定代表单位成本降低。
2026-10-29 22:19:45
645
原创 Java 27 的 TLS 新能力,为什么不能拿来证明 HTTP/2 不再堵塞?
升级 TLS、减少复制、扩大 HTTP/2 流并发,都可能影响网关,但它们解决的不是同一件事。把几个开关一起打开,再写一个没有基线的“吞吐提升百分比”,很难判断究竟发生了什么。
2026-10-28 09:20:02
643
原创 自适应反压别一高一低反复跳:给控制器留一段保持区间
显存压力刚过阈值就砍并发,稍一回落又全放开,下一轮又打满。控制器看似一直在工作,系统却被它推着振荡。指标有噪声、上报有延迟,推理任务结束也不是开关一关就立刻释放全部资源。
2026-10-28 09:19:04
683
原创 模型不可用时回退 FAQ,为什么要明确告诉用户这是离线答案?
模型服务不可用后,网关返回一段流畅的静态答案,页面也继续打字。看起来体验保持住了,但用户可能把它当成实时库存、订单状态或个性化优惠。把降级藏得太好,有时会扩大误解。
2026-10-28 09:18:01
658
原创 成本先到还是订单先到?实时关联别把后来的那一半丢了
本例把每个会话的成本汇总与订单汇总各视为一个最终输入,先等齐再输出。真实系统若有多笔订单、退款和费用更正,需要定义修订版本,不能直接把这里的单次结果模型套过去。Flink ProcessFunction 文档说明定时器按键和时间戳去重,也说明处理时间定时器在恢复后可能立即触发。旧定时器不应该把新一轮状态清掉。下面用纯 Java 展示世代检查,不声称已经运行了 Flink。return;
2026-10-28 09:16:51
668
原创 值班交接给人还是给 Agent,都别只留一句“系统正常”
当前正常,有事电话联系”听起来很轻松,却把下一班最需要的信息省掉了:哪个告警暂时静默、哪条路由还在降级、刚执行的动作有没有观察期,以及谁有权决定回退。
2026-10-28 09:14:37
684
原创 Prompt 缓存命中之前:租户、模型和规则版本都在键里吗?
两位用户问了同一句“这件商品能退吗”,答案可能仍然不同:所属店铺、购买时间和会员权益都可能影响结果。只对问题做哈希,即使完全没有哈希碰撞,也可能返回另一份权限域里的答案。
2026-10-27 21:52:32
669
原创 GPU 温度参与路由之前,先检查这条指标是不是旧的
一张卡上次上报温度很低,不代表它现在适合接单。指标代理断连后,缓存里可能还留着十分钟前的漂亮数字。若负载均衡把缺失值填成零,最不可观测的节点反而会拿到最高权重。
2026-10-27 21:51:39
610
原创 断流后删掉重复前缀,为什么仍不能叫“无损续接”?
上一段回答停在“退款将于”,新模型接着输出“退款将于三个工作日内到账”。删掉重叠前缀,看起来能接上;但新答案也可能接着说“审核完成后处理”。文本连接顺畅,不代表事实、工具状态和结构化数据都一致。
2026-10-27 21:49:45
685
原创 Token 计量流水线:重复消息不重算,比批量累加更早要解决
用量消息从网关进入队列,再进入费用系统,通常会遇到重投。消费者算完钱但来不及提交确认,下一次又收到同一条消息。若代码只会,消息系统越努力保证送达,账单就越容易翻倍。
2026-10-27 20:07:34
557
原创 缓存为什么会集体过期?先把持续时间和业务日期分开
缓存 TTL 是“从写入开始存多久”,活动规则是“在某个时区的某一日结束”。把二者都写成一个毫秒时间戳,可能暂时能跑,却容易在机器校时、时区转换和批量预热时暴露问题。
2026-10-27 20:05:55
694
原创 SSE 消费变慢以后:队列限 100 条,为什么内存仍可能涨?
大模型输出是一条长连接,客户端却不一定一直快。移动网络暂停几秒,网关如果继续接收上游输出,就必须有人存放这些还没发走的内容。把队列容量写成 100 条并不能限制内存:一条事件可能只有几十字节,也可能装着整段工具结果。
2026-10-26 22:46:41
1076
原创 双发模型请求时,输掉的那个回调该去哪?
为了压低长尾延迟,有些网关会在等待一段时间后再发一个备用请求。第二条请求有机会先回来,也有机会和第一条几乎同时完成。真正棘手的不是“谁先回包”,而是两边都回包以后,谁还能向用户写内容、谁负责结算,以及两个都失败时谁结束会话。
2026-10-26 22:46:04
741
原创 KEDA 想扩到 20 个副本,不等于现在就有 20 份可用算力
队列变长,指标触发,控制器提高副本数,调度器找到节点,进程启动,模型加载,探针就绪,最后才开始接流量。这是一条链。把第一步发生的时间写成“扩容完成耗时”,会在大促时高估可用容量。
2026-10-26 22:45:27
695
原创 跨厂商切换前,熔断器还欠一次受控探测
连续几次失败后把供应商标成不可用,代码很容易写。难点在恢复:如果所有请求同时看到冷却期结束,都去“试一下”,恢复中的服务会再次被打满;如果从来没有探测,它又可能永远留在黑名单里。
2026-10-26 22:44:49
1284
原创 发布冻结后还要改配置:先让同一个请求始终看到同一版规则
把规则放进,只能解决部分并发访问问题。一次模型调用先读了新路由、再读了旧预算、最后按另一版价格结算,容器没有报错,业务却已经把三份配置拼成了一份不存在的规则。
2026-10-26 22:44:12
1152
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅