java - 快速检查服务器是否有 Activity 的 Web 服务器(多线程)

标签 java multithreading performance sockets httpurlconnection

我想检查大量(数千个)网站,如果它们仍在运行。因为我想删除 HostFile Wikipage about Hostfiles 中的 unececarry 条目。 我想分两阶段进行。

  1. 检查端口 80 是否正在运行
  2. 检查 HTTP 响应代码(如果不是 200,我必须检查网站)

我想要多线程,因为如果我想检查数千个地址,我不能等待超时。 这个问题只是关于第一步。

我遇到了问题,大约 1/4 的连接尝试不起作用。如果我重试那些不起作用的大约 3/4 的工作?我没有正确关闭套接字吗?我是否遇到了打开套接字的限制? 默认情况下我运行 16 个线程,但使用 8 或 4 个线程也有同样的问题。 我有什么遗漏的吗

我稍微简化了代码。 这是线程的代码

public class SocketThread extends Thread{

  int tn;
  int n;
  String[] s;
  private ArrayList<String> good;
  private ArrayList<String> bad;

  public SocketThread(int tn, int n, String[] s) {
    this.tn = tn;
    this.n = n;
    this.s = s;
    good = new ArrayList<String>();
    bad = new ArrayList<String>();
  }

  @Override
  public void run() {
    int answer;
    for (int i = tn * (s.length / n); i < ((tn + 1) * (s.length / n)) - 1; i++) {
      answer = checkPort80(s[i]);
      if (answer == 1) {
        good.add(s[i]);
      } else {
        bad.add(s[i]);
      }
      System.out.println(s[i] + " | " + answer);
    }
  }
}

这是 checkPort80 方法

public static int checkPort80(String host) 
  Socket socket = null;
  int reachable = -1;
  try {
    //One way of doing it
    //socket = new Socket(host, 80);
    //socket.close();

    //Another way I've tried
    socket = new Socket();
    InetSocketAddress ina = new InetSocketAddress(host, 80);
    socket.connect(ina, 30000);
    socket.close();
    return reachable = 1;
  } catch (Exception e) {
  } finally {
    if (socket != null) {
      if (socket.isBound()) {
        try {
          socket.close();
          return reachable;
        } catch (Exception e) {
          e.getMessage();
          return reachable;
        }
      }
    }
  }
}

关于线程,我创建一个线程数组列表,创建它们并 .start() 它们,然后立即 .join() 它们,将“God”和“Bad”保存到文件中。

感谢帮助。

PS:我首先重命名了 Hosts 文件,这样它就不会影响进程,所以这不是问题。


编辑:
感谢 Marcelo Hernández Rishr,我发现 HttpURLConnection 似乎是更好的解决方案。它工作得更快,我还可以获得 HttpResponseCode,无论如何我也对此感兴趣(只是认为它会慢得多,然后只检查端口 80)。一段时间后我仍然突然收到错误,我想这与 DNS 服务器认为这是 DOS 攻击 ^^ (但我应该进一步检查错误是否在其他地方)也仅供引用,我使用 OpenDNS,所以也许他们只是不喜欢我^^。 x4u 建议在线程中添加 sleep() ,这似乎让事情变得更好一些,但它是否会帮助我提高每秒的条目数,我不知道。

不过,我(到目前为止)无法达到我想要的速度(10+ 条目/秒),甚至每秒 6 条目似乎也不起作用。 以下是我测试的一些场景(到目前为止,所有场景都没有任何 sleep())。

number of  time i get first round  how many entries where  entries/second
threads    of errors               processed until then
10         1 minute 17 seconds     ~770 entries            10
8          3 minute 55 seconds     ~2000 entries           8,51
6          6 minute 30 seconds     ~2270 entries           5,82

我会尝试找到线程和 sleep 的最佳位置(或者如果出现很多错误,可能只是暂停一分钟)。 问题是,主机文件有 100 万个条目,每秒一个条目需要 11 天,我想大家都明白,这是不可预期的。 有没有办法动态切换 DNS 服务器? 还有其他建议吗? 我应该将新问题作为单独的问题发布吗?

感谢您迄今为止的帮助。 我将在大约一周内发布新结果。

最佳答案

我有 3 条建议可以帮助您完成任务。

  1. 也许您可以使用类 HttpURLConnection
  2. 最多使用 10 个线程,因为您仍然受到 CPU、带宽等的限制。
  3. 列表 goodbad 不应该是线程类的一部分,如果您有 main 方法并执行 static 操作,它们可能可以是该类的静态成员同步方法可将成员从任何线程添加到两个列表。

关于java - 快速检查服务器是否有 Activity 的 Web 服务器(多线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6236954/

相关文章:

php - 顺序 strpos() 比具有一个 preg_match 的函数更快?

java - 即使在 pom.xml 中定义,也无法导入 keycloak

Java不捕获异常

python - Python 守护进程关闭问题的调试技术

c++ - 这些函数中哪个运行得更快?

mysql - 优化属性值数据库中的 Mysql 查询

java - Struts2中我们需要定制StrutsPrepareAndExecuteFilter吗?

java - 无法解决 Log Forging Fortify 问题

java - 如何从线程返回

c++ - QThreadPool 示例