当前位置: 代码迷 >> java >> 如何从URL中剖析导致程序出现问题的方法?
  详细解决方案

如何从URL中剖析导致程序出现问题的方法?

热度:41   发布时间:2023-07-31 10:53:30.0

我已经用Java编写了一个软件,该软件通过使用代理发送HTTP请求来检查代理是否正常工作。 它并行发送请求,使用ThreadPool运行100多个线程。

以下方法用于检查单个代理:

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

现在:CPU使用率在某些时候变得很高,我尝试使用JVisualVM对其进行性能分析。 我得到以下结果:

它声明我有“ Abdandoned连接清理线程”,但是我的代码使用尝试资源的方法来打开HttpURLConnection的输入流,并且我找不到离开开放连接的任何实例。 除了该方法中的流,我没有打开其他任何流。 而且,看起来parseURL(Java的URL对象中使用的一种方法)正在消耗100%的CPU时间。

请注意,它会更新SQL数据库以报告代理是否正常工作.MySQL数据库的更新是sync synchronized()

为什么会发生这种情况,我该如何解决?

编辑

我添加了一个Thread.sleep(50); 在将每个代理检查发送到exectuor服务之前(在上面的代码中很明显),我还向命令行添加了参数-XX:+UseParallelGC 它似乎可以持续更长的时间,但是几个小时后,CPU使用率仍然很高,并且程序崩溃了。

outputStream也应该关闭。 同时建立100个以上的连接确实会浪费CPU资源,尤其是在大多数代理可用时。