PHP 8.3 升级后,那个「慢查询」其实是 json_encode 的锅
This post is available in 简体中文 only — the original follows.
上周把一个小服务从 8.1 升到 8.3,升级完压测,某个接口的 P99 从 40ms 涨到 180ms。第一反应是数据库,抓了慢日志,一条都没有。第二反应是 OPcache 没生效,查了 opcache_get_status(),命中率正常。
最后是 xdebug 抓栈抓出来的:一个返回大数组的接口,json_encode 占了 60% 的时间。这个数组里混着几个 DateTimeImmutable 对象和一堆 null 字段,以前没人管,因为数据量小,压测也没覆盖到。数据量一涨,编码开销就露出来了。
我做了什么:一是给 DTO 加 JsonSerializable,把 DateTime 提前格式化成字符串,避免 encode 阶段反射;二是那几个永远为 null 的字段,在 SQL 层就 COALESCE 掉,或者干脆不 select。改完 P99 回到 55ms 左右,还是比 8.1 慢一点,但能接受。
说回来,这不是 8.3 的问题。8.3 的 json_encode 在我这台机器上没变慢,是我们自己把「接口返回什么就 encode 什么」当默认了。想问问各位:你们的接口层,是习惯在仓储层就组装好纯标量数组,还是让 json_encode 自己去处理对象?后一种写法省事,但数据一涨,谁来兜底?
0
Approval 100% · 0 comments · 33 Reads

0 comments
No comments yet — be the first.