代码之家  ›  专栏  ›  技术社区  ›  Marcio Aguiar

限时服务

  •  1
  • Marcio Aguiar  · 技术社区  · 17 年前

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

    谢谢!

    2 回复  |  直到 17 年前
        1
  •  1
  •   erickson    17 年前

    由于调用之间需要延迟,我建议 java.util.Timer java.util.concurrent.ScheduledThreadPoolExecutor . Timer 非常简单,完全适合 Executor 可以处理所有这些。无论哪种情况,都要使用固定延迟方法,而不是固定速率方法。

    polls


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

    如果第二种情况是你所想的,你的 run() blocking 在队列上,直到收到请求,然后记录时间。处理请求后,再次检查时间。如果时间差小于一秒, sleep

    还有一件事需要注意,该服务可能能够在一个请求中接受多个查询,这将减少开销。如果是这样,请通过屏蔽来利用这一点 take() 对于第一个元素,然后使用 poll() queue BlockingQueue<? 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". */
    
        2
  •  1
  •   James Anderson    17 年前

    您需要定义一个本地“代理服务”,您的本地客户端将调用该服务。

    本地代理将接收请求并将其传递给真实服务。但仅以每秒一条消息的速度。

    你如何做到这一点在很大程度上取决于你可用的技术。

    最简单的是具有静态和同步LastRequestTime长的多线程java服务;“时间戳变量。(尽管您需要一些代码技巧来保持请求的顺序)。

    更复杂的服务可以让工作线程接收请求,并将其放置在队列中,由单个线程接收请求并将其传递给真实的服务。

    推荐文章