java - 乐观缓存并发设计模式

标签 java design-patterns concurrency

我有一个在服务器集群上运行的 Web 服务。此 Web 服务执行一些内部处理,然后可能会调用会产生费用的外部服务。

我想放入一些缓存,这样如果我收到对服务的相同请求(这肯定会发生),那么我就不必重复处理,既节省了处理时间/功率,也节省了处理成本服务调用的外部部分。

但是,当我有以下限制时,我正在努力弄清楚如何管理这个缓存

  • 该服务在多个网络服务器上运行以实现高可用性和可扩展性
  • 该请求最多可能需要 5 秒才能响应,但与此同时,我可能收到了 2 或 3 个其他相同的请求。

在分布式环境中工作时,我如何才能推迟执行其他服务调用,直到第一个服务调用响应(因此在缓存中可用)。

我考虑过采用前端代理模式并在代理内建立一个相同请求的队列,这样当第一个返回时,它也可以将相同的响应返回给其他请求。这是正确的模式,还是有更好的并发模式来处理这种情况?

最佳答案

你可以

  1. 计算请求的加密散列
  2. 查看此散列的结果是否已在数据库中,如果是,则返回它
  3. 以“结果待定”状态将散列存储在数据库中
  4. 调用网络服务并用结果更新数据库中的行。

在第 2 步,如果哈希已经在数据库中,并且处于“结果待定”状态,您可以每 X 毫秒轮询一次数据库,并在结果存在后最终返回结果。

当然,细节决定成败,因为如果发生错误,您必须决定要做什么:

  • 您是否为所有后续的相同请求返回错误?
  • 是否让等待线程重新尝试调用网络服务?
  • 你会返回一个错误,但只是一段时间,然后重试吗?

关于java - 乐观缓存并发设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9377415/

相关文章:

python - 如何以编程方式并发驱动 Ansible?

c# - C# 中的并发集合

java - Web 应用程序上的 RabbitMq 异常

java - 没有这样的算法-bcrypt

java - 替换嵌套开关/ifelse 的设计模式

concurrency - Go lang关闭管道死锁

java - Android java模块 "jar"文件依赖问题

java - php很有限吗?

java - Java 1.6 中是否有用于类似 lambda 语句的 OOB Command 接口(interface)?

asp.net-mvc - mvc中禁用或不禁用按钮的逻辑