1

如果一个请求的id 不存在,Cache 不会得到它,请求将通过数据库进行查询。

不存在的 id 请求将全部命中 Database,如果这是攻击,缓存将无法保护 Database。

很快数据库就关闭了。

那么我能做些什么来防止这种类型的攻击呢?

PS 数据库数据太多。如果一个 id 只访问一次,Null Object Cache将不起作用。

4

1 回答 1

0

您可以缓存一个 Optional,如果响应为空,您将在第一个请求中保存 Optional.absent()。只要数据库中存在关联的 Id,就必须使该缓存的 Optional 实体无效,或者如果您在不断增长的缓存中遇到内存问题,则必须尽快使该实体无效。

我喜欢 guava 的 Cache 和 Optional 类,因为我认为它们解决了大多数可能的问题,我将在我的示例中使用它们:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Optional;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;


public class OptionalCacheUsage {

  private static final Cache<Id, Optional<Entity>> cache = CacheBuilder.newBuilder()
      .softValues()
      .expireAfterWrite(5, TimeUnit.MINUTES)
      .build();

  private static final Database db = Databases.getDatabase();

  Entity findEntity(final Id requestedId) throws ExecutionException, EntityNotFoundException {
    final Optional<Entity> optionalEntity = cache.get(requestedId, new Callable<Optional<Entity>>() {

      @Override public Optional<Entity> call() throws Exception {
        return Optional.fromNullable(db.getById(requestedId));
      }});
    if (optionalEntity.isPresent()) {
      return optionalEntity.get();
    } else {
      throw new EntityNotFoundException();
    }
  }

  Id saveEntity(final Entity newEntity) {
    final Id savedId = db.save(newEntity);
    cache.invalidate(savedId);
    return savedId;
  }
}
于 2013-07-04T04:46:09.223 回答