知识卡片
Deprecated但仍可用的API埋下的隐藏坑:兼容性妥协容易让人沿用旧写法而踩坑
内容
Elasticsearch 2.x把Filtered Query标记为不推荐使用(deprecated),官方建议改用bool查询里的must和filter参数来实现同样的效果,但deprecated不等于完全禁用——2.x版本里Filtered Query依然是可以正常使用的,这个”能用但不建议用”的过渡状态,恰恰成了百姓网升级过程中一个很深的坑。原因在于百姓网当时面临的是1.x和2.x集群同时共存、滚动式升级的场景,为了实现平滑升级、减少对现有查询代码的改动,团队很自然地选择继续沿用Filtered Query这个写法(反正2.x里还能正常跑),结果这个选择成为了导致前述GC死循环问题的两个深坑之一——切换到bool查询代替filtered之后,GC问题得到了明显缓解。团队自己也坦言,这类问题”算不上是Bug”,Filtered Query官方文档也只写了deprecated而不是不可用,正是这种表面上”技术上没有任何阻拦”的暧昧状态,反而最容易让人在需要平滑过渡、图省事的场景下,无意识地继续沿用一个实际上已经暗藏问题的旧写法。这个案例给出了一条对待”deprecated但仍可用”这类API状态的重要警示:deprecated这个标记本身传递的信息,往往不只是”未来某个版本会被移除”这么简单,很多时候它同时也在暗示”这个旧实现路径在底层已经和新版本的其他优化路径产生了摩擦或不兼容”,即使当前版本里它依然能跑通、看起来没有报错,也不代表它的运行时行为和性能特征和被推荐的新写法是等价的——尤其是在版本升级、需要兼顾新旧兼容的场景下,”能不能继续用旧写法”和”应不应该继续用旧写法”是两个完全不同的问题,图省事沿用deprecated但仍可用的旧接口,恰恰是升级过程中最容易被忽视、却可能造成深层次问题的雷区。