Skip to content

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

@GuiSong01

Description

@GuiSong01

描述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);
    }

截图

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

额外的细节和日志

  • 版本:
  • 错误日志
  • 配置:
  • 平台和操作系统

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions