Быстрая проверка серверов на активный веб-сервер (многопоточный) - PullRequest
1 голос
/ 04 июня 2011

Я хочу проверить огромное количество (тысячи) веб-сайтов, если они все еще работают.Потому что я хочу избавиться от ненужных записей в моем HostFile Wikipage о Hostfiles .Я хочу сделать это в двухэтапном процессе.

  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;
        }
      }
    }
  }
}

О потоках, я делаю ArrayList из потоков, создаю их и .start () их исразу после этого я .join () получаю «Бог» и «Плохой», сохраняю их в файлы.

Помощь приветствуется.

PS: Сначала я переименовываю файл Hosts так,что это не влияет на процесс, так что это не проблема. Edit: Благодаря Марсело Эрнандесу Ришру я обнаружил, что подключение HttpURLC кажется лучшим решением.Он работает быстрее, и я также могу получить HttpResponseCode, который мне тоже все равно был интересен (просто подумал, что это будет намного медленнее, чем просто проверка порта 80).Я все еще через некоторое время неожиданно получаю ошибки, я думаю, это связано с тем, что DNS-сервер думает, что это DOS-атака ^^ (но я должен изучить дальше, если ошибка лежит где-то еще) и к тому же я использую OpenDNS, так что, возможно, онипросто я не нравлюсь ^^.x4u предложил добавить Sleep () в Threads, что, кажется, немного улучшает ситуацию, но поможет ли мне поднять записи / секунду, я не знаю.

Тем не менее, я не могу (на данный момент) достичь скорости, которую я хотел (10+ записей в секунду), даже 6 записей в секунду, похоже, не работают.Вот несколько сценариев, которые я тестировал (до сих пор без сна).

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

Я постараюсь найти подходящее место с потоками и сном (или, может быть, просто остановлю все на одну минуту, если яполучить много ошибок).Проблема в том, что существуют Hostfiles с одним миллионом записей, что на одну запись в секунду займет 11 дней, что, я думаю, все понимают, не ожидается.Существуют ли способы переключения DNS-серверов на лету?Любые другие предложения?Стоит ли публиковать новые вопросы как отдельные вопросы?

Спасибо за помощь до сих пор.Новые результаты я опубликую через неделю.

Ответы [ 2 ]

0 голосов
/ 04 июня 2011

У меня есть 3 предложения, которые могут помочь вам в вашей задаче.

  1. Возможно, вы можете использовать класс HttpURLConnection
  2. Используйте максимум 10 потоков, потому чтовы по-прежнему ограничены процессором, пропускной способностью и т. д.
  3. Списки good и bad не должны быть частью вашего класса потока, возможно, они могут быть статическими членами класса, если у вас есть основнойметод и статические синхронизированные методы для добавления членов в оба списка из любого потока.
0 голосов
/ 04 июня 2011

Сокеты обычно пытаются корректно завершить работу и ждать ответа от порта назначения.Пока они ждут, они по-прежнему блокируют ресурсы, что может привести к сбою последовательных попыток подключения, если они были выполнены, пока было слишком много открытых сокетов.

Чтобы избежать этого, можно отключить задержку перед подключением сокета:

socket.setSoLinger(false, 0);
...