mainLogic
根据入参提供的地理位置点,计算并输出其所在 country, city, service providers
原始逻辑
i. 先读缓存(redis), 若命中则直接返回
ii. 若未命中,则需要根据两部分信息构造结果。两部分分别是:1. 调用接口 foo; 2. 去查配置中心 configCenter
iii. 将上述结果写入缓存(注意其中包含了两部分信息)
iv. 返回结果
存在的问题
缓存有效期为1天,所以修改 configCenter 之后无法立即生效,要等到1天后缓存过期,才会生效。
修改缓存逻辑
作了两点改动——
- 当缓存命中时,仍然去读
configCenter, 而不是直接使用缓存中的配置信息; - 既然不再使用缓存中的配置信息,那么写缓存时也不必包含
configCenter了,只保留调用foo的结果即可。
伪 bug
上线时,先部署了一台机器(deploy canary), 观察到许多日志的 X 字段都为空,究其原因应该是从 configCenter 读到的那部分信息,是空值。但是反复看代码逻辑,又无法解释何以如此。
排查了很久,最后才意识到,这应当是符合预期的——
i. 一台机器(canary)部署了新代码
ii. 该机器发生 mainLogic 调用
iii. 缓存未命中,于是调用接口 foo, 并将结果写入缓存(注意这时 mainLogic 再遇到相同入参的话,缓存将会命中)
iv. 去查 configCenter
v. 将 iii 和 iv 两部分结果组合后,返回
vi. 非 canary 机器发生 mainLogic 调用,入参与 ii 相同
vii. 缓存命中,但其中仅包含 borders 调用结果,configCenter 那部分为空值。但是旧代码会认为,只要命中缓存那么其中就包含了全部所需信息,于是就返回了 configCenter 为空的结果。
Summary
涉及缓存的修改,必须充分考虑造成的影响,尤其是上线部署多台机器,过程中会发生什么,都要做到心中有数。