Я написал программный продукт на 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.У меня есть следующие результаты:
Это говорит о том, что у меня есть «Поток очистки удаленного соединения», однако мой код использует попытку с ресурсами, чтобы открытьВходной поток HttpURLConnection
, и я не могу найти ни одного случая, когда бы я оставил открытое соединение.Я не открываю никакие другие потоки кроме тех в методе.Более того, похоже, что parseURL (метод, используемый в объекте URL-адреса Java) занимает 100% моего процессорного времени.
Обратите внимание, что он обновляет базу данных SQL, чтобы сообщить, работает ли прокси. Обновление базы данных MySQL: synchronized()
.
Почему это происходит, и как я могу это исправить?
EDIT
Я добавил Thread.sleep(50);
перед отправкой каждого прокси-чека в службу exectuor (это видно из кода выше) Я также добавил аргумент -XX:+UseParallelGC
в моей командной строке.Кажется, это длится дольше, но через несколько часов загрузка ЦП все еще очень высока, и программа вылетает.