在REST

时间:2015-08-02 22:57:22

标签: java rest concurrency jersey request

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

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

2 个答案:

答案 0 :(得分:1)

您可以创建一个唯一的对象来锁定每个"键。"其中键是一些请求参数,在本例中为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:客户只需提出一个请求
  • 亲:您没有重新计算结果
  • Pro:没有单个客户的等待时间比串行案例增加
  • Con:您在计算期间持有VM线程,这是每个客户端。看到你有观点的客户,这不应该成为一个问题。
  • Con:考虑清理缓存的良好时间表可能会很棘手

答案 1 :(得分:0)

在开发与许多REST服务的集成以避免不必要的服务调用期间,我们在收到的响应数据库(JSON字符串)中创建现金

对于每个此类现金记录,我们保存用于调用Web服务的 params 。如果我们有请求,我们将params与数据库中现有的params进行比较。我们仅针对新的params向REST发出实际请求。此外,我们也有必要,因为有些请求不是免费的。

此外,我们还有一个参数,显示每小时(或几天)内每张现金记录的验证日期,以便在一段时间后我们自动发出真实请求,如果它是很久以前制作的获得免费信息。

这种方法是在使用REST服务几年后创建的,它在我们的解决方案中非常有用。