从今天起开一个固定栏目:每天读一本书,把里面的东西压缩到 20 分钟内读完,再写点自己的看法。方向是金融、AI、历史这三块——前两块是饭碗,最后一块是让人不至于把今年发生的事都看成世界末日。 这个栏目不打算做成读书笔记的搬运。我做了八年 Java 和 AI,又自己跑过出海盘子、也清零过两次,读这些书
一次没顶住的流量 去年大促,预估峰值 8000 QPS,实际来了 1.4 万,订单服务被打挂 12 分钟。复盘发现:我们的容量评估靠的是"去年×2"的拍脑袋,没有真实压测支撑,对系统的真实拐点一无所知。那天凌晨告警炸了,扩容来不及,限流没配,全靠手动重启扛,资损不小。这次我把容量评估正经做了一遍,把
几个年头里反复踩的坑 建表时随手选类型,上线后不是慢就是错。我整理了团队里最高频的几类字段选型问题,新项目开工前照着过一遍。这些坑每一个都对应过一次线上事故或一次漫长的数据迁移,所以值得写下来反复提醒。 varchar 长度 有人图省事一律 varchar(255),其实 MySQL 在 utf8m
自研鉴权撑不住了 公司原来的登录是各个系统各写一套 Session,互不相通。用户在我们三个产品里要登三次,运营吐槽了半年。我们决定用 Spring Authorization Server(基于 Spring Security 6)搭一个统一认证,做 OAuth2 授权中心,让所有子系统一处登录、
半夜的 OOM,却没留下证据 有天凌晨一个服务 OOM 自杀重启,等我早上到公司,堆已经被 GC 一遍、镜像重建了,啥都看不到。这种"看过现场却没拍照"的故障最折磨人,只能凭日志猜是哪块吃内存,结果猜了一上午猜错方向。从那以后我定下规矩:任何 Java 服务 OOM 必须自动留证,不能让现场随重启蒸
我们为什么离不开 Nginx 后端是 Spring Boot 起的 8080 服务,但直接把 8080 暴露在公网既不安全也难扩展。一来没有 TLS 卸载,二来单实例挂了没容灾,三来限流得在每个应用里写。Nginx 在我们架构里身兼数职:反向代理、负载均衡、限流、长连接优化。它配一次能管一片服务,是
集群重启后要 40 分钟才能变绿,问题出在分片数 我们用 ES 做商品搜索和日志检索,版本从 7.15 升到 8.0(2022 年 2 月发布,正式用上)。3 月一次故障演练,重启集群后主分片恢复花了 40 分钟才变绿,期间搜索不可用。排查下来,根因是分片数设错了:一个 200 GB 的索引被切成
为什么关心 AOT Spring Boot 3.0 刚出,主打对 GraalVM 原生镜像的支持。我们一个网关侧边车想压启动时间,原来 JVM 冷启动要 2 秒多,在弹性伸缩场景里每次扩容都得等,想试试原生镜像能不能降到几百毫秒。决定试 AOT 之前,我先把"AOT 到底是什么"搞清楚,不然很容易把
一个偶发的空指针 服务启动时偶发 NPE,堆栈指向缓存预热器里取到的 RedisTemplate 是 null。但 RedisTemplate 明明配好了——问题是它被用在了配置类的 @PostConstruct 里,而那时它依赖的连接工厂还没就绪。重启三四次才复现一次,最磨人。这种"时灵时不灵"的
用户投诉:刚改完昵称又变回去了 那天下午客服转来 7 个工单,都是"改了资料刷新又回旧值"。我第一反应是缓存,清了一遍没用。查监控才发现,是主从延迟在作怪——前端查到了还没同步过去的旧数据。更诡异的是,有的用户反馈"改完看是对的,过两秒刷新又变回去",典型的读到了从库旧快照。 定位过程 用户在主库改
为什么想上 Mesh 团队有 30+ 微服务,TLS、重试、熔断这些逻辑散落在每个 Dubbo/Spring Cloud 应用里,升级一次 SDK 全员陪跑。一次熔断规则改版,光是让各服务升级 SDK 就花了两周,还有三个老服务因为没人维护迟迟不动。我们想试试把这部分下沉到基础设施,于是拉了一套 I
周五下午的告警 2022-03-31 Spring4Shell(CVE-2022-22965)被公开,我们安全群里炸了。我负责的两个服务跑在 Spring Boot 2.3 上,得立刻确认是否在影响范围内。应急响应的第一步不是升级,而是确认影响面——盲目全量升级可能引入别的问题,先搞清楚"我中没中"
下单接口越来越慢 createOrder 接口 RT 一度到了 800ms,点进去一看,主链路里塞了发短信、记风控、推积分三件"顺带"的事。它们慢一点,用户下单就卡一下。最糟的是,积分服务抖动时连下单都失败了,核心链路被旁路拖死。监控里下单 RT 的 P99 曲线和积分服务的 RT 曲线几乎同涨同落
从一次支付状态建模说起 早些年写支付结果,我习惯用一个 enum 加一堆 if: enum PayStatus { SUCCESS, FAILED, PENDING, REFUNDED } void handle(PayStatus s) { if (s == SUCCESS) { ...
那个 3000 行的 Service 接手交易核心模块时,OrderService.java 有 3128 行,下了 47 个 @Autowired 的 DAO 和远程 client。任何一处改动我都得屏住呼吸。上周一个改下单幂等的小需求,回归测试就跑了三轮,改动 8 行、提心吊胆一整天。更糟的是,
一次奇怪的吞吐量瓶颈 大促前给订单流水 topic 扩分区,从 12 个加到 48 个,本以为吞吐能线性提升,结果生产端 P99 延迟不降反升,监控上看到 broker 端请求队列开始堆积。翻了半天才意识到:分区数过了拐点就是负担,不是越多越猛。 这事其实之前踩过一次。那回我们是 consumer