掘金点赞数错乱背后的黑魔法:是熔断?还是应届生偷偷改了代码?

96 阅读4分钟

掘金点赞数错乱背后的黑魔法:是熔断?还是应届生偷偷改了代码?

作者:天天摸鱼的java工程师 发布于:掘金


今天早上刷掘金时,发现了一个奇怪的现象:京东云开发者的主页上显示“文章被点赞 1”,但文章底下明明“点赞 0”

image.png 作为一个写了8年Java、看过无数“诡异 bug”的后端开发者,我第一反应不是“掘金是不是挂了”,而是:

“嘿,这里面一定有故事。”

于是我打开 IDEA,泡上一杯咖啡,开始复盘这背后的可能性。有点像在调试别人留下的“炸弹代码”。


一、初步现象复盘

我们来看两个关键数据:

  • 右侧成就栏显示:文章被点赞 1
  • 文章底部实际显示:点赞 0

再加上“关注了 0、人关注者 1”,但从动态来看,这个账号显然是官方号,还在持续发文。

这不是简单的“页面没刷新”,而是数据源之间出现了不一致

那问题来了:是前端展示错了?后端数据同步出问题?还是缓存没更新?


二、从架构角度猜测几个可能性

1. 缓存未及时同步

这是最常见的锅:

  • 用户点赞后,点赞数写入了 Redis 缓存。
  • 页面右侧的“成就栏”直接走缓存读取。
  • 文章详情页则是实时查数据库,或者缓存未命中。

结果就是:缓存有值,详情页没更新。也许缓存更新策略是异步的,或者 TTL 设置太长。

可能的修复建议:

  • 点赞后主动刷新缓存。
  • 或者采用“写透缓存”策略。

2. 服务被熔断,降级返回旧数据

掘金这种流量大的平台,通常都会做服务熔断、降级处理。如果点赞统计服务短时间内不可用,可能会:

  • 从 fallback 中拿旧数据(比如昨天的点赞数)
  • 或者直接返回默认值 0

这时用户看到的就是与实际不一致的“历史快照”。

熔断的背锅方式大概是这样的:

@HystrixCommand(fallbackMethod = "getDefaultLikeCount")
public int getLikeCount(String articleId) {
    return likeService.getLikeFromDB(articleId);
}

public int getDefaultLikeCount(String articleId) {
    return 0; // 默认值
}

3. 应届生“优化”了点赞逻辑

作为老程序员,我经历过不少“应届生上线没测好”的故事。

比如:为了优化页面性能,把点赞列表的查询逻辑改为按小时批次更新;或者搞了个“新点赞系统”,但只改了一半接口,结果新旧系统的数据打架。

“上线前测过吗?”

“测了呀,本地是没问题的……”

这类问题最难查,因为逻辑是对的,数据却不统一。


4. 前端状态计算错误

掘金前端可能用了 React 或 Vue,点赞组件拿的是内部状态,而成就栏是另一个模块独立渲染,他们之间的数据源不同步,导致渲染出的 UI 不一致。

甚至可能是点赞后用了乐观更新,但失败了没 rollback。


三、我在生产中遇到过类似的问题

有一次我们做用户画像统计时,也遇到过类似的“点赞不一致”问题:

  • 用户在帖子 A 点了赞,但因为 Kafka 消息延迟,用户画像服务晚了几分钟才更新;
  • 此时用户刷新主页看到“点赞+1”,但换个页面又变回“点赞 0”。

最终我们采用了 **“最终一致性 + 强提醒”**的策略:

  1. 用户操作后立即更新本地缓存(展示用)
  2. 后台异步更新用户画像服务
  3. 页面展示时加提示:“数据可能略有延迟”

四、结语:bug 是最好的老师

这次掘金的小 bug,也许只是缓存策略没统一,也许是哪个后端服务挂了,甚至可能是哪个实习生上线的时候忘了改一个字段。

但作为开发者,我们可以从中学到很多:

  • 分布式系统中的数据一致性问题
  • 缓存与数据库的同步机制
  • 服务降级与熔断策略的应用与副作用
  • 前后端解耦带来的状态管理挑战

👨‍💻 最后说一句:

缓存是把双刃剑,用得好叫性能优化,用不好叫“点赞消失术”。

欢迎大家一起探讨类似的技术问题,评论区见!


如果你也遇到过类似奇葩 bug,欢迎留言分享!
点赞是对老程序员最大的支持 🙏


📌 作者简介:Java后端开发8年,从事过电商、金融、云原生方向,热爱技术,也爱吐槽。