从今天起开一个固定栏目:每天读一本书,把里面的东西压缩到 20 分钟内读完,再写点自己的看法。方向是金融、AI、历史这三块——前两块是饭碗,最后一块是让人不至于把今年发生的事都看成世界末日。 这个栏目不打算做成读书笔记的搬运。我做了八年 Java 和 AI,又自己跑过出海盘子、也清零过两次,读这些书
背景 上周联调一个订单状态机,本地用 Redis 做幂等缓存。单元测试里我习惯用 Mockito 把 RedisTemplate 整个 mock 掉,结果上线后在缓存过期那块直接炸了。mock 根本没覆盖 TTL 和原子自增的真实语义,自测全绿却带着隐患上了线。 复盘那次事故,根因是我们对"缓存是否
准备升级 Spring Security 6:配置风格全变了 Spring Security 6.0 要在 2022 年 11 月随 Spring Boot 3.0 一起 GA,但我们不想等上线了再手忙脚乱。10 月初我就拉了 6.0 的候选版本做预研,最大的冲击是:WebSecurityConfi
订单系统重构:一个"订单"对象膨胀到了 3000 行 我们老订单系统里有个 Order 类,承载了下单、改地址、退款、发票、物流查询……所有逻辑,文件 3000 多行,改一处怕动全身。重构时我用 DDD 的聚合(Aggregate)思想重新切分,核心问题其实就一个:聚合边界划在哪。划错了,要么事务跨
一段 SQL 在 Java 里换行,我存成了诡异的格式 前几天 Code Review,看到有人拼一条多行 SQL 用了老套路: String sql = "SELECT id, name, price FROM product " + "WHERE category = ? AND
缓存和数据库又双叒不一致了 我们的商品详情页用"先更新 DB,再删缓存"的策略。大多数时候没问题,但运营一次批量改价后,部分用户看到的价格还是旧的,持续了十几分钟。根因是并发下的时序问题:线程 A 更新 DB、还没删缓存时,线程 B 读了旧 DB 值并写回缓存,导致 A 的删除"删了个寂寞",脏数据
面试官问:100 万人抢 1000 件商品怎么设计 前阵子做架构分享,被同事用一道经典题考住:"100 万并发抢 1000 件商品,怎么保证不超卖、系统还不挂?"这题看着老,但真要落地,每一层都有坑。我把我们实际做过的秒杀系统的设计要点拆开讲——不是教科书,是踩过坑的版本。 要点一:库存扣减,必须原
为什么我们卡在 JDK 8,却决定直接跳 17 团队基础组件升级评审会上,有人提议"升到 JDK 11 过渡一下"。我投了反对票:既然要动,不如直接到 JDK 17——它是继 8 之后第二个长期支持版本(LTS),2021 年 9 月发布,生态已经足够成熟,而 11 到 17 之间没有第二个 LTS
一个 ES 查询,把节点 CPU 打到了 95% 运营后台有个"订单检索"接口,平时挺快,某天加了"按创建时间排序 + 关键词模糊"后,单查询 CPU 占用飙升,集群一个节点到了 95%,其他查询全被拖慢。我用 profile API 抓了执行计划,发现罪魁是把本该放 filter 的条件写进了 q
GC 选型的争论:Shenandoah 还是 ZGC 我们一个时延敏感的交易网关,之前用 G1,业务高峰 P99 偶尔冲到 400 ms,排查发现是 G1 的 Mixed GC 有 100~200 ms 的停顿。组里就"换哪个低延迟 GC"吵开了:有人挺 Shenandoah,有人挺 ZGC。我干脆
面试被问:REQUIRES_NEW 到底开了几个连接 前阵子面一个五年经验的候选人,我随口问:"方法 A 用 REQUIRED 调方法 B,B 用 REQUIRES_NEW,这俩用的是同一个数据库连接吗?"对方答"应该是同一个吧,都在一个事务里"。这其实是个很常见的误解。REQUIRES_NEW 会
凌晨告警:服务起不来了,日志只有一行 一个深夜,我们的风控服务在发布后反复重启失败。Pod 日志最后一行永远是这句话: java.lang.OutOfMemoryError: unable to create new native thread at java.base/java.lang.
对账发现:账户余额和流水对不上 3 分钱 做交易系统最怕"状态对不上"。我们有个积分账户服务,某天对账脚本报:用户 A 的余额是 1200,但流水累加只有 1199.97。差 3 分钱,谁也说不清是哪笔操作漏了。传统的"改余额 + 插流水"两条写,因为中途异常出现过不一致。痛定思痛,我把核心域改成了
分库分表后,运营要查"跨商家跨库的订单" 我们订单库按 user_id 哈希分了 16 个库、每库 64 张表。单用户的订单查询很顺,因为都在同一个分片。直到运营提了个需求:"给我看最近 30 天、金额大于 5000、状态是退款中的所有订单"——这个查询跨了所有库所有表,没有分片键可路由。组员在周会
注册中心抖动,推送延迟到了 8 秒 去年我们把配置中心/注册中心从 Nacos 1.x 升到 2.0,起因是一次线上抖动:一个服务下线,但网关隔了 8 秒才感知到,期间一大波请求打到了已死的实例。翻 Nacos 1.x 的源码才知道,它用的是客户端 10 秒一次 HTTP 轮询去拉变更,服务端有了新
慢查询告警响了,但我不知道是哪条 SQL 有天早上 Prometheus 报了一条 mysql_slow_queries 突增,我登录数据库一查 SHOW PROCESSLIST,满屏都是 Sending data 的查询,根本分不清谁是元凶。那时候我们的慢查询治理还是"出问题了才去看日志",属于事