gpt4 book ai didi

java - 限时服务

转载 作者:行者123 更新时间:2023-11-30 05:16:43 34 4
gpt4 key购买 nike

我正在开发一个向 Musicbrainz 网络服务发出请求的应用程序。我在 musicbrainz 手册中读到每秒不要向网络服务发出超过一个请求,否则客户端 IP 将被阻止。

为了使此限制对服务客户端透明,您建议采用什么架构。

  • 我想调用一个方法(例如 getAlbuns),它应该仅在上次请求后 1 秒发出请求。
  • 我还想一次调用 10 个请求,并且服务应该处理排队,并在可用时返回结果(非阻塞)。

谢谢!

最佳答案

由于调用之间需要延迟,我建议 java.util.Timer java.util.concurrent.ScheduledThreadPoolExecutor Timer非常简单,并且完全适合这个用例。但如果稍后确定其他调度要求,则单个 Executor可以处理所有这些。无论哪种情况,都使用固定延迟方法,而不是固定速率方法。

重复任务polls请求对象的并发队列。如果有待处理的请求,任务将执行该请求,并通过回调返回结果。对服务的查询和要调用的回调是请求对象的成员。

应用程序保留对共享队列的引用。要安排请求,只需将其添加到队列中即可。

<小时/>

澄清一下,如果执行定时任务时队列为空,则不会发出请求。简单的方法就是结束任务,调度程序会在一秒后调用该任务再次检查。

但是,这意味着即使最近没有处理任何请求,启动任务也可能需要一秒钟的时间。如果这种不必要的延迟是无法忍受的,那么编写自己的线程可能比使用 Timer 更好。或ScheduledThreadPoolExecutor 。在您自己的计时循环中,如果您选择阻塞空队列直到有请求可用,您就可以更好地控制调度。内置计时器不保证在上一次执行完成后等待一整秒;他们通常根据任务的开始时间进行安排。

如果您想到的是第二种情况,您的run()方法将包含一个循环。每次迭代均以 blocking 开始在队列中,直到收到请求,然后记录时间。处理完请求后,再次检查时间。如果时间差小于一秒,sleep其余的。此设置假设一个请求开始与下一个请求开始之间需要一秒的延迟。如果一个请求结束与下一个请求之间需要延迟,则不需要检查时间;睡一秒钟就可以了。

还需要注意的是,该服务可能能够在单个请求中接受多个查询,这将减少开销。如果是这样,请通过阻止take()来利用这一点。对于第一个元素,然后使用 poll() ,可能需要很短的阻塞时间(5 毫秒左右),以查看应用程序是否发出更多请求。如果是这样,这些可以捆绑在对服务的单个请求中。如果queueBlockingQueue<? extends Request> ,它可能看起来像这样:

    Collection<Request> bundle = new ArrayList<Request>();
bundle.add(queue.take());
while (bundle.size() < BUNDLE_MAX) {
Request req = queue.poll(EXTRA, TimeUnit.MILLISECONDS);
if (req == null)
break;
bundle.add(req);
}
/* Now make one service request with contents of "bundle". */

关于java - 限时服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/784214/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com