如何在JAVA中在非常精确的时间发送HTTP请求。

huangapple go评论78阅读模式
英文:

How to send a HTTP request at a very precise time in JAVA

问题

我想在一个非常精确的时间窗口内(例如从2020年8月20日00:00:00到2020年8月20日00:00:50)发送多个并行的HTTP请求(例如通过异步的OkHttp)。

http://www.quartz-scheduler.org支持精确到1秒的精度。

如何安排它们?

英文:

I want to send several, parallel HTTP requests (for example via async OkHttp) in a very precise time window (eg from 20.08.2020 00.00.00 to 20.08.2020 00.00.50) .

http://www.quartz-scheduler.org has a precision up to 1second.

How to schedule them?

答案1

得分: 1

如果您关心服务器接收时间,而不是客户端开始发送的时间,那么您应该使用一些请求预热 OkHttp。

对于 HTTP/1.1 连接,您需要多个连接。检查连接池大小,并根据需要进行调整。

对于 HTTP/2 连接,在发送结果时准备就绪。如果您担心任一请求的大小,您可能希望通过使用多个客户端实例来覆盖 OkHttp 的默认行为,以避免在共享套接字上出现线头阻塞。

如上所述,对于 Java 线程调度,请使用 ScheduledExecutorService,并可能在事件之前唤醒,然后自旋直到精确的毫秒。您无法使用 nanoTime,因为它与任意时代相关,因此毫秒精度可能是您能做到的最好精度。

英文:

If you care about the time they are received by the server as opposed to when the client starts sending then you should prewarm OkHttp with some requests.

For HTTP/1.1 connections you need multiple connection. Check the connection pool size and tune it if needed.

For a HTTP/2 connection ready when you go to send results. If you are worried about the size of any one request, you may want to override the default behaviour of OkHttp by having multiple client instances to avoid head of line blocking on the shared socket.

As suggested above, for java thread scheduling use ScheduledExecutorService and probably wake before the event and spin until the exact millisecond. You can't use nanoTime since it's related to an arbitrary epoch, so millisecond accuracy is probably the best you can do.

答案2

得分: 1

你可以在Java中使用CompletableFuture来调度任务。以下是用于调度HTTP任务的示例代码:

TimeUnit可以用于以毫秒为单位进行调度TimeUnit.MILLISECONDS)。

public static <T> CompletableFuture<T> schedule(
    ScheduledExecutorService executor,
    Supplier<T> command,
    long delay,
    TimeUnit unit
) {
    CompletableFuture<T> completableFuture = new CompletableFuture<>();
    executor.schedule(
        () -> {
            try {
                return completableFuture.complete(command.get());
            } catch (Throwable t) {
                return completableFuture.completeExceptionally(t);
            }
        },
        delay,
        unit
    );
    return completableFuture;
}

有关CompletableFuture的概念,请参阅以下文章:

https://www.artificialworlds.net/blog/2019/04/05/scheduling-a-task-in-java-within-a-completablefuture/

另外,您还可以编写自己的调度程序:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

编辑部分:

您还可以尝试使用以下代码来进行调度:

scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
LocalDateTime ldt = LocalDateTime.parse("2020-10-17T12:42:04.000", formatter);
ZonedDateTime nextRun = ldt.atZone(ZoneId.of("America/Los_Angeles"));

if (now.compareTo(nextRun) > 0)
    nextRun = nextRun.plusDays(1);

Duration duration = Duration.between(now, nextRun);
long initialDelay = duration.toMillis();

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new MyRunnableTask(),
    initialDelay,
    TimeUnit.DAYS.toMillis(1),
    TimeUnit.MILLISECONDS);

(注意:上述代码中的MyRunnableTask需要您自己实现。)

英文:

You can use Scheduling a task in Java within a CompletableFuture to schedule your task:
Something like this to scheule your http task:

TimeUnit can be used to schedule till milliseconds.(TimeUnit.MILLISECONDS)

    public static &lt;T&gt; CompletableFuture&lt;T&gt; schedule(
    ScheduledExecutorService executor,
    Supplier&lt;T&gt; command,
    long delay,
    TimeUnit unit
) {
    CompletableFuture&lt;T&gt; completableFuture = new CompletableFuture&lt;&gt;();
    executor.schedule(
        (() -&gt; {
            try {
                return completableFuture.complete(command.get());
            } catch (Throwable t) {
                return completableFuture.completeExceptionally(t);
            }
        }),
        delay,
        unit
    );
    return completableFuture;
}

Refer this article for concept for completablefuture:

https://www.artificialworlds.net/blog/2019/04/05/scheduling-a-task-in-java-within-a-completablefuture/

Alternate you can write your own scheduler:

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

EDIT:

Try using this :
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

ZonedDateTime now = ZonedDateTime.now(ZoneId.of(&quot;America/Los_Angeles&quot;));

 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyy-MM-dd&#39;T&#39;HH:mm:ss.SSS&quot;);
LocalDateTime ldt= LocalDateTime.parse(&quot;2020-10-17T12:42:04.000&quot;, formatter);
ZonedDateTime nextRun= ldt.atZone(ZoneId.of(&quot;America/Los_Angeles&quot;));

        


if(now.compareTo(nextRun) &gt; 0)
    nextRun = nextRun.plusDays(1);

Duration duration = Duration.between(now, nextRun);
long initalDelay = duration.toMillis();


ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);            
scheduler.scheduleAtFixedRate(new MyRunnableTask(),
    initalDelay,
    TimeUnit.DAYS.toMillis(1),
    TimeUnit.MILLISECONDS);

huangapple
  • 本文由 发表于 2020年8月20日 05:25:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63495222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定