Java 如何在google guava缓存中传递两个或多传递一个参数而不是键
我已经使用谷歌番石榴缓存创建了一个缓存 这是我的实现Java 如何在google guava缓存中传递两个或多传递一个参数而不是键,java,caching,microservices,google-guava-cache,Java,Caching,Microservices,Google Guava Cache,我已经使用谷歌番石榴缓存创建了一个缓存 这是我的实现 private final LoadingCache<Long, DistChannel> channelServiceCache = CacheBuilder.newBuilder().maximumSize(50) .refreshAfterWrite(4, TimeUnit.HOURS).build(new CacheLoader<Long, DistChannel>() {
private final LoadingCache<Long, DistChannel> channelServiceCache = CacheBuilder.newBuilder().maximumSize(50)
.refreshAfterWrite(4, TimeUnit.HOURS).build(new CacheLoader<Long, DistChannel>() {
@Override
public DistChannel load(Long channelId) throws InvalidRequestException, TException {
long start = System.nanoTime();
try {
return channelService.getDistributionChannelById(channelId, SOLR_API_KEY);
} catch (InvalidRequestException e) {
log.error("Cannot look up channel: {}", channelId, e);
String serviceName = StringUtils.isNotBlank(e.getServiceName()) ? e.getServiceName() : CHANNEL_SERVICE;
throw e.setServiceName(serviceName + "." + SERVICE_NAME + "." + hostName);
} finally {
log.info("Channel Service call, ChannelId: {} Time : {}", channelId,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
}
}
@Override
public ListenableFuture<DistChannel> reload(final Long channelId, final DistChannel oldValue) throws Exception {
ListenableFutureTask<DistChannel> task = ListenableFutureTask.create(new Callable<DistChannel>() {
public DistChannel call() {
long start = System.nanoTime();
try {
return channelService.getDistributionChannelById(channelId, SOLR_API_KEY);
} catch (TException e) {
log.error("Cannot look up channel: {}", channelId, e);
}finally {
log.info("reload Channel Service call, ChannelId: {} Time : {}", channelId,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start));
}
return oldValue;
}
});
executorServiceForCache.execute(task);
return task;
}
});
private final LoadingCache channelServiceCache=CacheBuilder.newBuilder().maximumSize(50)
.refreshAfterWrite(4,TimeUnit.HOURS).build(新缓存加载程序(){
@凌驾
public DistChannel load(Long channelId)抛出InvalidRequestException,texException{
长启动=System.nanoTime();
试一试{
返回channelService.getDistributionChannelById(channelId,SOLR\u API\u密钥);
}捕获(无效请求异常e){
错误(“无法查找通道:{}”,通道ID,e);
String serviceName=StringUtils.isNotBlank(e.getServiceName())?e.getServiceName():通道服务;
抛出e.setServiceName(serviceName+“+服务名称+”+主机名);
}最后{
log.info(“频道服务调用,ChannelId:{}时间:{}”,ChannelId,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-start));
}
}
@凌驾
public ListenableFuture重新加载(最终长通道ID,最终DistChannel oldValue)引发异常{
ListenableFutureTask任务=ListenableFutureTask.create(new Callable()){
公共频道呼叫(){
长启动=System.nanoTime();
试一试{
返回channelService.getDistributionChannelById(channelId,SOLR\u API\u密钥);
}捕获(特克斯){
错误(“无法查找通道:{}”,通道ID,e);
}最后{
log.info(“重新加载通道服务调用,ChannelId:{}时间:{}”,ChannelId,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime()-start));
}
返回旧值;
}
});
executorServiceForCache.execute(任务);
返回任务;
}
});
现在在channelService.getDistributionChannelById方法中,我需要paas两个值,即channelId和apiKey
目前,它作为apiKey的工作状态是稳定的。但是现在apiKey被修改为这个contant~timestamp。例如:
SOLR_API_密钥~123456789
所以我的问题是:
如何在channelServiceCache.get(键,
extraparam在此)而不修改键
我试过的东西:
我创建了一个Key对象,其中将存在我的实际密钥和apiKey,并将其作为密钥传递到channelServiceCache,但这将终止缓存的用途,因为每次终止都将被视为一个新密钥,因为它在apiKey中包含时间戳
我可以用谷歌番石榴做这个吗
编辑:我还错过了一件事:
服务将为相同的channelId提供相同的输出,API密钥仅用于身份验证、日志记录和监视请求计数。但我想这是有道理的,若我可以使用缓存中相同的channelID服务下一个请求,那个么apiKey将永远不会被传递到实际的服务(实际的日志记录和监视正在进行)有没有其他方法来实现此功能而不真正扼杀google guava的目的。如果每个通道id和API密钥的服务输出不同,则API密钥需要是缓存密钥的一部分 如果无论什么API键,输出都是相同的,则可以使用任何API键或始终相同的API键
从调用者传递API键,但缓存该值没有意义,或者本质上是随机选择API键。一旦值在缓存中,您将返回一个结果,该结果是使用与前一个调用方不同的API键检索的。您的问题定义似乎不一致。根据您的描述,您可以通过实现一个密钥类来满足您的需求,该类同时持有通道id和API密钥,但实现hashCode并基于通道id等于soleloy。但它到底为什么有用:您的channelService需要两个参数来完成其契约是有原因的。如果无论API密钥是什么,您都可以重用通道ID,那么为什么您首先需要它?我可以重用它,但它不是常量值。不,服务将为同一个通道ID提供相同的输出,API密钥仅用于身份验证、日志记录和监视请求计数。同意@cruftex。如果
service
将APIKey用于任何目的,则它是缓存密钥的一部分。例如:您为id=1,apiK=1
请求一个新的“频道”channelService.getDistributionChannelById
被调用,它对apiKey=1
执行“日志记录”,您将获得DistChannel
对象。然后您请求另一个id=1,apiKey=2
。根据您的说法,缓存应该返回相同的DistChannel
实例。因此不应调用channelService.getDistributionChannelById
,并且其apiKey=2的日志记录也不应发生。结论:您不需要它/也可以使用任何随机值。事实证明,我的要求正是您所说的。谢谢你指出这个@GPI