Java Rest:如何处理数千个相同的请求

Java Rest:如何处理数千个相同的请求,java,rest,web-services,Java,Rest,Web Services,我有一个RESTWeb服务,它基本上和一个数字一样长,并提供数字是否为素数,即纯文本的true或false 数百万用户正在使用这项服务 现在一个用户正在发送非常大的数字,比如(15-20位数字/大数字),而我的服务需要时间来计算这个数字是否为素数。该用户连续发送数千个相同号码的请求。那么如何处理这成千上万的请求呢 例如: 在请求中发送1012213232324343号码,我的服务将花费3秒来确定该号码是否为素数。现在他每秒发送1000个请求 如何处理这种情况?您可以在数据库中存储大于给定位数的值

我有一个RESTWeb服务,它基本上和一个数字一样长,并提供数字是否为素数,即纯文本的true或false

数百万用户正在使用这项服务

现在一个用户正在发送非常大的数字,比如(15-20位数字/大数字),而我的服务需要时间来计算这个数字是否为素数。该用户连续发送数千个相同号码的请求。那么如何处理这成千上万的请求呢

例如:

在请求中发送1012213232324343号码,我的服务将花费3秒来确定该号码是否为素数。现在他每秒发送1000个请求


如何处理这种情况?

您可以在数据库中存储大于给定位数的值。无论何时收到这样的数字,您都可以在数据库中存储它是否为素数。您还可以使用缓存来存储最后n个不同的值,因此,当请求一个数字时,您可以检查它是否太长。如果没有,简单计算一下。如果它太长,请在缓存中搜索它。如果它在那里,就把它还给我。如果不存在,请在数据库中搜索它。如果存在,则将其添加到缓存中(并可能删除最早的值),然后将其返回给用户。如果它甚至不在数据库中,则计算它,将其存储在数据库中,将其添加到缓存中,并将答案返回给用户

@NotThreadSafe 
public CheckIfPrime extends Servelet  {
    private Long lastNumber;
    private Long isLastNumberPrime;

    public Long operation(ServeletRequest req, ServeletResponse res) {
        if(getNumberFromRequest(req) == lastNumber) {
            return isLastNumberPrime;
        } else {
             return checkForPrimeNumber(getNumberFromRequest);
        }
    }

}
使用同步原语来尊重类的不变量和后置条件(一种方法是使用
AtomicLong
而不是
Long

如果您认为请求的数量可能太大(耗尽内存),请考虑使用分布式缓存。


对于非常高的TPS,使您的应用程序具有反应性。
checkForPrime()
操作可以异步完成。为什么要阻止调用线程?

您可以利用内存中的逐出缓存,根据最大内存大小或TTL调整其参数。有关一般信息,请检查,例如。有很多实现,但我推荐Ben Manes的实现,因为它效率高。您可以使用DB,但在这种情况下,它可能比新计算更昂贵,因此,我可能会将缓存限制在内存中。

我想你可以使用内存中的缓存。有这么多用户的数字也不同……缓存太大了……不要认为缓存是一个好的解决方案……所以你可以发挥神奇的作用……:使用内存来节省处理时间,或者为每个请求腾出更多的处理时间。。。。没有第三种选择,如果您有智能缓存方法,您可以节省一些内存,而不是简单地将每个请求放入缓存。为了避免用户发送大量请求,您必须对它们进行速率限制。@VJS欢迎您。如果它解决了你的问题,你可以考虑接受它作为正确的答案。不管怎样,我祝你解决这个有趣的问题好运。这是一个很好的答案。这是一种直截了当的方法。我只是在想,我们能做些别的事情来处理这种情况吗。我的意思是,有没有更好的解决方案。@VJS您可以使用一些额外的优化技术。例如,如果数字之和可以被3整除,那么大的数字就不是素数。如果最后一个数字是pair,那么大的数字就不是素数。如果你有另一个非抵押贷款,这是接近这个数字,你可以检查差异。例如,如果另一个非素数可以被7整除,而差值可以被7整除,那么你就得到了一个非素数。在计算任何DB之前,我会检查IO成本(给定高度并发的查找)与计算时间。此外,如果没有合理的逐出策略,DB将很快占据整个存储空间,因为问题是无限的:)给定请求的绝对数量,命中与上一个相同值的概率几乎为零,因此此优化是无用的。哦,你为什么认为它将接近于零?正如OP所提到的,可能有数千个请求包含相同的数字。这不是最后一个:正如OP所说的“数百万用户正在使用该服务”,而且肯定会有数千个相同数字的数千次重复,因此与上一次相比,每次都会是一个新的数字。此外,您的示例不是线程安全的:您应该为值/指示符对使用原子引用,并相应地交换它。在这种情况下,我们可以使用包含数字及其布尔结果的ConcurrentHashMap吗?请参阅我的(单独)答案,鉴于问题是无限的,您的代码将很快耗尽标准映射上的内存,是否并发。