如果一个请求不存在id ,则缓存无法获取,请求将通过数据库进行查询。
不存在的id请求将全部命中数据库,如果这是攻击,则缓存无法保护数据库。
数据库很快关闭。
那么我该怎么做才能防止这种类型的攻击?
P.S。数据库有太多数据。如果一个id只访问一次, Null对象缓存将无效。
答案 0 :(得分: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;
}
}