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

在JAVA中如何在非常精确的时间发送HTTP请求,java,scheduled-tasks,okhttp,Java,Scheduled Tasks,Okhttp,我想在一个非常精确的时间窗口(例如从20.08.2020 00.00.00到20.08.2020 00.00.50)内发送几个并行HTTP请求(例如通过异步OkHttp) 精度高达1秒 如何安排它们?如果您关心服务器接收它们的时间,而不是客户端开始发送它们的时间,那么您应该使用一些请求来预热OkHttp 对于HTTP/1.1连接,您需要多个连接。检查连接池大小,并根据需要进行调整 当您转到发送结果时,HTTP/2连接已准备就绪。如果您担心任何一个请求的大小,您可能希望通过使用多个客户端实例来覆盖

我想在一个非常精确的时间窗口(例如从20.08.2020 00.00.00到20.08.2020 00.00.50)内发送几个并行HTTP请求(例如通过异步OkHttp)

精度高达1秒


如何安排它们?

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

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

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


如上所述,对于java线程调度,请使用ScheduledExecutorService,可能会在事件之前唤醒并旋转到精确的毫秒。您不能使用nanoTime,因为它与任意历元相关,因此毫秒精度可能是您所能做到的最好的精度。

您可以使用Java在可完成的将来调度任务来调度您的任务: 类似于以下内容来安排您的http任务:

TimeUnit可用于调度到毫秒。(TimeUnit.millizes)


您可以使用Executors.newScheduledThreadPool(..)创建一个
ScheduledExecutorService
,并使用它精确地计划执行。如果您需要更多功能(如Quartz,具有持久性等),您可以围绕
ScheduledExecutorService
实现自己的逻辑,例如,它在启动应用程序时从数据库加载序列化执行计划,等等。我不确定在您建议的解决方案中,我应该在哪里设置发送请求的确切日期和时间。我可以看到
延迟
单位
,但不幸的是,一段时间内没有任何参考点。请从问题中解释如何使用您的解决方案以获得所需的时间窗口。如果这能解决您的问题,请检查编辑部分。
如上所述,对于java线程调度,请使用ScheduledExecutorService,可能会在事件前唤醒并旋转到精确的毫秒-我不知道如何达到这个精度。如何估计“唤醒时间”并在规定的时间窗口内达到预期效果?请您提供任何PoC,好吗?如果您在原始问题中给出一个您一直在尝试的示例,这样其他人就可以帮助您解决您的具体问题,这可能会更容易。另外还有很多假设,例如,它们是到同一个主机,是文件上传还是头请求。我已经检查了几个不同的JAVA Scheduler LIB,但我可以得到的最大粒度达到秒级。我检查了Quartz调度器,ApacheTurbine的FulcrumQuartz,cron4j,但到目前为止运气不好
    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;
}
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 initalDelay = duration.toMillis();


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