Как мне профилировать метод из URL, который вызывает проблемы в моей программе? - PullRequest
0 голосов
/ 13 февраля 2019

Я написал программный продукт на Java, который проверяет, работают ли прокси, отправляя HTTP-запрос с использованием прокси.Он отправляет запросы параллельно с более чем 100 потоками, работающими с использованием ThreadPool.

Следующий метод используется для проверки отдельного прокси:

public boolean isWorkingProxy() {
    //Case of an invalid proxy
    if(proxyPort == -1) {
        return false;
    }

    HttpURLConnection con = null;

    //Perform checks on URL
    //IF any exception occurs here, the proxy is obviously bad.
    try {
        URL url = new URL(this.getTestingUrl());
        //Create proxy
        Proxy p = new Proxy(this.testingType, new InetSocketAddress(this.proxyIp, this.proxyPort));
        //No redirect
        HttpURLConnection.setFollowRedirects(false);
        //Open connection with proxy
        con = (HttpURLConnection)url.openConnection(p);
        //Set the request method
        con.setRequestMethod("GET");
        //Set max timeout for a request.
        con.setConnectTimeout(this.timeout);
        con.setReadTimeout(this.timeout);
    } catch(MalformedURLException e) {
        System.out.println("The testing URL is bad. Please fix this.");
        return false;
    } catch (ProtocolException e) {
        System.out.println("Invalid request type provided (Not GET / POST / Valid type)");
        return false;
    } catch(IOException e) {
        System.out.println("Failed to open connection with url using proxy.");
        return false;
    }

    try(
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            ) {

        //read text response
        String inputLine = null; StringBuilder response = new StringBuilder();
        while((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }


        //A valid proxy!
        return con.getResponseCode() > 0;

    } catch(Exception e) {
        return false;
    }
}

Следующий код показывает, как я инициирую потоки:

Deque<String> proxies = DB.getProxiesToCheck();
while(proxies.isEmpty() == false) {
    try {
        String[] split = proxies.pop().split(":");

        //Submit every check for this proxy
        //There are a total 7 checks right now.
        for(int i = 0; i < checks.length; i++) {
            executor.submit(new RunnableProxyRequest(split[0], split[1], checks[i]));
        }

    } catch(IndexOutOfBoundsException e) {
        continue;
    }
    //Wait 50ms before each proxy
    Thread.sleep(50);
}

Теперь: загрузка процессора в некоторых моментах становится довольно высокой, и я попытался профилировать его с помощью JVisualVM.У меня есть следующие результаты:

JVisualVM profiler image

Это говорит о том, что у меня есть «Поток очистки удаленного соединения», однако мой код использует попытку с ресурсами, чтобы открытьВходной поток HttpURLConnection, и я не могу найти ни одного случая, когда бы я оставил открытое соединение.Я не открываю никакие другие потоки кроме тех в методе.Более того, похоже, что parseURL (метод, используемый в объекте URL-адреса Java) занимает 100% моего процессорного времени.

Обратите внимание, что он обновляет базу данных SQL, чтобы сообщить, работает ли прокси. Обновление базы данных MySQL: synchronized().

Почему это происходит, и как я могу это исправить?

EDIT

Я добавил Thread.sleep(50); перед отправкой каждого прокси-чека в службу exectuor (это видно из кода выше) Я также добавил аргумент -XX:+UseParallelGCв моей командной строке.Кажется, это длится дольше, но через несколько часов загрузка ЦП все еще очень высока, и программа вылетает.

1 Ответ

0 голосов
/ 15 февраля 2019

OutputStream также должен быть закрыт.Одновременное выполнение 100+ подключений действительно стоит ресурсов ЦП, особенно когда доступно большинство прокси.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...