java - 在 REST 中处理相同的并发请求

标签 java rest concurrency jersey request

问候 SO 社区! 我有一个基于 Jersey 的 REST 应用程序。此应用程序(由于其客户端的性质)大致在同一时间(相隔约 2-5 秒)接收相同的 http 请求(其中 3-6 个)。 每个请求大约需要 10 秒来处理并带回大量数据(访问数据库、进行数据处理等)。 在一个理想的世界中,我想避免必须多次处理相同的请求,并且正在考虑编写某种请求过滤器,它只允许唯一的请求通过,而其他请求将被阻止,直到允许的请求返回. 被阻止的请求也会将相同的数据返回给调用者(通过在服务器上查找缓存的响应)

这种方法的优点/缺点是什么? 除了更改客户端逻辑之外,是否有更好的解决方案;)

最佳答案

您可以创建一个独特的对象来锁定每个“ key ”。其中关键是一些请求参数,在这个例子中是一个 String。这样你就可以保持请求(因为同步),一旦计算完成,两个客户端几乎同时得到结果。这样,客户端不必发出多个请求,而不是第一个请求的客户端必须等待第一个客户端填充缓存。

import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

public class Hold {
    private ConcurrentHashMap<String, String> holds =
            new ConcurrentHashMap<>(new HashMap<String, String>());

    // compose a "hash" for lack of better word, could append a timeout as well
    public String hashString (String string) {
        return string + "wackystuff";
    }

    public String doLongComputation () {
        // do crazy computation here
        return new String();
    }


    public synchronized String getResults (String key) {
        // give us a unique object for this key to lock on
        holds.putIfAbsent(key, hashString(key));

        // lock on that key
        synchronized (holds.get(key)) {
            // we have a non lock value so return it
            if (!holds.get(key).equals(hashString(key))) {
                // could do some timeout here
                return holds.get(key);
            }
            // the cache is empty so do the long computation
            holds.put(key, doLongComputation());
        }
        return holds.get(key);
    }

}

这只是一种狡猾的方法,Java Concurrency in Practice 一书有更强大的方法,它在第 5.19 节,代码示例可以在 here 中找到。 .

以下是这种方法的优缺点:

  • 优点:客户只需提出一个请求
  • Pro:你没有重新计算结果
  • 优点:与连续案例相比,单个客户的等待时间没有增加
  • 缺点:您在计算期间占用了一个 VM 线程,这是针对每个客户端的。鉴于您有查看客户,这应该不是问题。
  • 缺点:想出一个好的时间表来清除缓存可能很棘手

关于java - 在 REST 中处理相同的并发请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31777442/

相关文章:

java - 流排序问题

rest - 移动应用程序 + REST 后端中的 OpenID Connect 身份验证流程(使用 KeyCloak)

java - 是否有新版本的 ehcache-core 是最新版本的 Ehcache 的一部分?

java - 在自动化 Java 性能测试期间监控和记录系统指标的工具

visual-studio - 添加 "REST API Client..."菜单不可用

java - 如果 wait(timeout) 和 notifyAll() 被同一个对象锁定,timeout 是什么意思

java - 对学习 Java 并发的程序或小项目有什么建议吗?

java - 这个线程安全的字节序列生成器有什么问题?

java - 多线程上传多个文件时面临空指针

python - flask REST API 错误 : The view function did not return a valid response