Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apollo-ConfigService开启缓存后,过期缓存中配置需要校验大小写,会导致apollo-client填写APP_ID参数没有严格大小写的服务获取不到配置 #3529

Closed
3 tasks done
GuiSong01 opened this issue Feb 2, 2021 · 5 comments · Fixed by #4820
Labels
area/configservice apollo-configservice kind/report-problem Categorizes issue when someone report the problem he/she meeted stale

Comments

@GuiSong01
Copy link

GuiSong01 commented Feb 2, 2021

描述bug
Apollo-ConfigService开启缓存功能后,客户端填写的APP_ID参数没有严格区分大小写的服务会获取不到最新的配置。
不启用服务端缓存,不会校验APP_ID大小写的。
复现

通过如下步骤可以复现:

  1. apolloconfigdb.serverconfig表中字段config-service.cache.enabled设置成true,并重启Apollo-ConfigService服务
  2. Apollo上有一个项目Apollo-Demo
  3. 客户端有一个服务APP_ID=apollo-demo
  4. 启动客户端后,再发布一个配置,会发现客户端一直获取不到最新的配置

有问题的代码片段(从Apollo-ConfigService模块ConfigServiceWithCache类中抽出):

    //cache is out-dated
    if (clientMessages != null && clientMessages.has(key) &&
        clientMessages.get(key) > cacheEntry.getNotificationId()) {
      //invalidate the cache and try to load from db again
      invalidate(key);
      cacheEntry = configCache.getUnchecked(key);
    }

上述判断中has(key)实际是一个map的containsKey方法,大小写不同会导致比较失败,无法进入过期缓存的逻辑
期望
补充一个私有方法:

  boolean cacheOutOfDate(String key, ConfigCacheEntry cacheEntry, ApolloNotificationMessages clientMessages) {
    if (clientMessages == null || clientMessages.isEmpty()) {
      return false;
    }
    Iterator<Map.Entry<String, Long>> iterator = clientMessages.getDetails().entrySet().iterator();
    while (iterator.hasNext()) {
      Map.Entry<String, Long> detail = iterator.next();
      if (detail.getKey().toLowerCase().equals(key.toLowerCase()) && detail.getValue() > cacheEntry
              .getNotificationId()) {
        return true;
      }
    }
    return false;
  }

上面有问题的判断替换成私有的方法

    //cache is out-dated
    if (cacheOutOfDate(key, cacheEntry, clientMessages)) {
      //invalidate the cache and try to load from db again
      invalidate(key);
      cacheEntry = configCache.getUnchecked(key);
    }

截图

如果可以,附上截图来描述你的问题

额外的细节和日志

  • 版本:
  • 错误日志
  • 配置:
  • 平台和操作系统
@nobodyiam
Copy link
Member

ConfigServiceWithCache目前确实没有很好的处理客户端 appId 大小写不一致的问题,如果有好的想法和建议的话,欢迎提交 PR 大家一起 review 下。初步考虑,除了 invalidate cache 逻辑,cache 加载也需要处理一下,比如当客户端既有 apollo-demo,也有 apollo-Demo 的情况。

@GuiSong01
Copy link
Author

GuiSong01 commented Feb 3, 2021

mysql查询默认不区分大小写,apollo建表sql里面没有指定需要区分大小写,所以加载逻辑不需要修改吧?
@nobodyiam

@Anilople Anilople added area/configservice apollo-configservice kind/report-problem Categorizes issue when someone report the problem he/she meeted labels Feb 3, 2021
@nobodyiam
Copy link
Member

@GuiSong01 加载没问题,不过在缓存中会出现多个大小写不一样的 key,这部分需要考虑是加载的时候就 normalize 还是更新缓存的时候统一更新

@Q-RK Q-RK mentioned this issue Feb 6, 2021
4 tasks
@stale
Copy link

stale bot commented Jun 20, 2021

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in 14 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 20, 2021
@stale
Copy link

stale bot commented Jul 8, 2021

This issue has been automatically closed because it has not had activity in the last 7 days. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted". Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/configservice apollo-configservice kind/report-problem Categorizes issue when someone report the problem he/she meeted stale
Projects
None yet
3 participants