【问题标题】:Check the number of requests sent to a webpage检查发送到网页的请求数
【发布时间】:2020-11-07 16:30:42
【问题描述】:

我正在编写一个 Java 多线程应用程序,它可以访问数百万甚至数十亿不同 Web 服务器的 URL。我们的想法是检查这些 URL 是否给出有效的 200OK 响应或 404/其他代码。

我如何知道我的程序是否没有在他们的服务器上造成高流量? 我不希望发生 DOS 攻击。每台服务器有将近 800 万个 URL。

为了检查流量,我创建了一个托管在 http://localhost:8089/ 上的简单网页。我的应用程序访问该页面 200 万次,不是一次全部,而是一个接一个。我想知道我的代码在网络流量不超载的情况下的效率。

netstat 显示 TIME_WAIT 中有很多线程。

我如何知道此页面的流量。有什么软件可以用来跟踪这个吗?或者任何 Linux 命令之类的。我也愿意接受建议。

【问题讨论】:

    标签: java http https


    【解决方案1】:

    使用同步地图记住您访问每台服务器的时间。

    一种方法是检查之前的访问时间,如有必要,在方法本身中休眠:

    private static final Map<URL, Instant> lastAccessTimes = new HashMap<>();
    
    private static final Duration COOLDOWN = Duration.ofSeconds(60);
    
    public void contact(URL url)
    throws IOException,
           InterruptedException {
    
        URL server = new URL(url.getProtocol() + ":" + url.getAuthority());
    
        Instant now = Instant.now();
        long delay = 0;
    
        synchronized (lastAccessTimes) {
            Instant newAccessTime = now;
    
            Instant lastAccess = lastAccessTimes.get(server);
            if (lastAccess != null) {
                Instant soonestAllowed = lastAccess.plus(COOLDOWN);
                if (now.isBefore(soonestAllowed)) {
                    newAccessTime = soonestAllowed;
                    delay = now.until(soonestAllowed, ChronoUnit.NANOS);
                }
            }
    
            lastAccessTimes.put(server, newAccessTime);
        }
    
        if (delay > 0) {
            TimeUnit.NANOSECONDS.sleep(delay);
        }
    
        URLConnection connection = url.openConnection();
        // etc.
    }
    

    如果您不想冒着阻止线程池的风险,可以在冷却期后使用执行程序重试。比如使用 CompletableFuture 的默认线程池:

    private static final Map<URL, Instant> lastAccessTimes = new HashMap<>();
    
    private static final Duration COOLDOWN = Duration.ofSeconds(60);
    
    public void contact(URL url) {
        URL server;
        try {
            server = new URL(url.getProtocol() + ":" + url.getAuthority());
        } catch (MalformedURLException e) {
            logger.log(Level.WARNING,
                "Could not extract server from " + url, e);
            return;
        }
        
        Instant now = Instant.now();
    
        synchronized (lastAccessTimes) {
            Instant lastAccess = lastAccessTimes.get(server);
            if (lastAccess != null) {
                Instant soonestAllowed = lastAccess.plus(COOLDOWN);
                if (now.isBefore(soonestAllowed)) {
                    long delay = now.until(soonestAllowed, ChronoUnit.NANOS);
    
                    CompletableFuture.runAsync(() -> contact(url),
                        CompletableFuture.delayedExecutor(
                            delay, TimeUnit.NANOSECONDS));
                    return;
                }
            }
    
            lastAccessTimes.put(server, now);
        }
    
        try {
            URLConnection connection = url.openConnection();
            // etc.
        } catch (IOException e) {
            logger.log(Level.WARNING, "Could not contact " + url, e);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 2013-11-04
      • 2012-05-07
      • 1970-01-01
      • 2013-05-21
      相关资源
      最近更新 更多