Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在google guava缓存中传递两个或多传递一个参数而不是键_Java_Caching_Microservices_Google Guava Cache - Fatal编程技术网

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