HttpUrlConnection 在 CentOS 上 运行 时占用 100% CPU
HttpUrlConnection taking 100% CPU when running on CentOS
我有一个 HttPURLConnection 程序,它正在与 运行 在同一台机器上(在本例中为 CentOS)但部署在其他 tomcat 服务器上的某个应用程序建立连接。这意味着在部署在不同 tomcat 上的两个应用程序之间建立了一个 HttpConnection,其中两个 tomcat 都在同一台机器上 运行。
一切正常,当我发出一个请求时,我在 200 英里内得到了响应。
但是当应用程序通过 JMeter 并行加载 100 个请求 运行 以进行无限循环时,应用程序开始进行高 CPU 处理。
这是我的代码:
public String sendHttpGetReq(String urlParameters,String msisdn, InNodeConfig inNodeConfig, InNodeDetails inNodeDetails)
{
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] Inside sendHttpGetReq");
String response = "";
//response = "{\"id\":\"584371732\",\"status_billing\":\"INSUFFICIENT_FUNDS\",\"status_sms\":\"NO_SMS\"}";
String url = "";
URL obj = null;
HttpURLConnection con = null;
try
{
url = "http://"+inNodeConfig.getServerIp()+":"+inNodeConfig.getServerPort()+inNodeConfig.getServiceUri();
url = url+urlParameters;
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] url = "+url);
obj = new URL(url);
con = (HttpURLConnection) obj.openConnection();
con.setDoOutput(true);
con.setRequestMethod("GET");
con.setConnectTimeout(Integer.parseInt(inNodeConfig.getConTimeOut()));
con.setReadTimeout(Integer.parseInt(inNodeConfig.getConTimeOut())+1000);
int responseCode = con.getResponseCode();
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] HTTP Response Code : " + responseCode);
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] HTTP Response message : " + con.getResponseMessage());
if(responseCode == 202 || responseCode == 200)
{
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer responseBf = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
responseBf.append(inputLine);
}
in.close();
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] Response received = "+responseBf.toString());
response = responseBf.toString();
responseBf = null;
if(inNodeDetails.getOperator().equalsIgnoreCase("digicel"))
{
if(response.startsWith("Received"))
{
response = "ok";
}
else if(response.startsWith("{"))
{
// {"id":"185688","status_billing":"INSUFFICIENT_FUNDS","status_sms":"FAILED"}
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Parsing json response.");
Gson gson = new Gson();
JsonResponse jsonResponse = gson.fromJson(response, JsonResponse.class);
if(jsonResponse.getStatus_billing().equalsIgnoreCase("ok") || jsonResponse.getStatus_billing().contains("SUCCESS")){
response="ok";
}
else if(jsonResponse.getStatus_billing().equalsIgnoreCase("INSUFFICIENT_FUNDS"))
{
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Response received for INSUFFICIENT_FUNDS.");
response = "low balance";
}
else if(jsonResponse.getStatus_billing().equalsIgnoreCase("FAILED"))
{
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Failure Response received for some other reason.");
response = "nok";
}
else
{
if(inNodeDetails.getCountry().equalsIgnoreCase("JAM")||inNodeDetails.getCountry().equalsIgnoreCase("HAI")){
response=jsonResponse.getStatus_billing();
}
else{
gson = null;
jsonResponse = null;
}
}
}
else
{
if(inNodeDetails.getCountry().equalsIgnoreCase("HAI") && response.contains("EXCEPTION"))
{
response = "ok";
}
else
{
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Unknown response.");
response = "nok";
}
}
}
}
else if(responseCode == 502 || responseCode == 500)
{
if(inNodeDetails.getCountry().equalsIgnoreCase("HAI") || inNodeDetails.getCountry().equalsIgnoreCase("JAM"))
{
response = "ok";
}
else
{
response = "nok";
}
}
else
{
response = "nok";
/*Map<String,List<String>> responseMap = con.getHeaderFields();
for (Map.Entry entry : responseMap.entrySet()) {
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "header key = "+entry.getKey() + " value = " + entry.getValue());
}*/
}
return response;
}
catch(SocketTimeoutException ex)
{
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "Read Timeout occurs for msisdn = "+msisdn);
return "ReadTimeout";
}
catch(ConnectTimeoutException ex1)
{
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "ConnectTimeoutException occurs for msisdn = "+msisdn);
return "ConnectionTimeout";
}
catch(ConnectException ex2)
{
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "ConnectException occurs for msisdn = "+msisdn);
return "ConnectionTimeout";
}
catch(JsonSyntaxException ex3){
response=null;
return response;
}
catch(MalformedJsonException ex4){
response=null;
return response;
}
catch(Exception e)
{
Logger.sysLog(LogValues.error, this.getClass().getName(),"["+msisdn+"] Internal Error occured"+coreException.GetStack(e));
return response;
}
finally
{
response = null;
url = null;
obj = null;
con.disconnect();
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"Calling GC.");
System.gc();
}
//return response;
}
但是,相同的代码 运行 在每秒大约 50 个请求的生产环境中非常好。
当我使用 JVisualVM 和 Sampler 时,我了解到这种方法 "sendHttpGetReq" 需要很长时间和高 CPU 处理。但是从代码中,我找不到代码应该阻止所有 CPU.
的具体原因
这是采样器屏幕截图:
请指出可能是什么问题?
我认为 finally 调用的 System.gc() 方法可能会导致问题。
建议您评论 System.gc() 并尝试一下。
我有一个 HttPURLConnection 程序,它正在与 运行 在同一台机器上(在本例中为 CentOS)但部署在其他 tomcat 服务器上的某个应用程序建立连接。这意味着在部署在不同 tomcat 上的两个应用程序之间建立了一个 HttpConnection,其中两个 tomcat 都在同一台机器上 运行。
一切正常,当我发出一个请求时,我在 200 英里内得到了响应。 但是当应用程序通过 JMeter 并行加载 100 个请求 运行 以进行无限循环时,应用程序开始进行高 CPU 处理。
这是我的代码:
public String sendHttpGetReq(String urlParameters,String msisdn, InNodeConfig inNodeConfig, InNodeDetails inNodeDetails)
{
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] Inside sendHttpGetReq");
String response = "";
//response = "{\"id\":\"584371732\",\"status_billing\":\"INSUFFICIENT_FUNDS\",\"status_sms\":\"NO_SMS\"}";
String url = "";
URL obj = null;
HttpURLConnection con = null;
try
{
url = "http://"+inNodeConfig.getServerIp()+":"+inNodeConfig.getServerPort()+inNodeConfig.getServiceUri();
url = url+urlParameters;
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] url = "+url);
obj = new URL(url);
con = (HttpURLConnection) obj.openConnection();
con.setDoOutput(true);
con.setRequestMethod("GET");
con.setConnectTimeout(Integer.parseInt(inNodeConfig.getConTimeOut()));
con.setReadTimeout(Integer.parseInt(inNodeConfig.getConTimeOut())+1000);
int responseCode = con.getResponseCode();
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] HTTP Response Code : " + responseCode);
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] HTTP Response message : " + con.getResponseMessage());
if(responseCode == 202 || responseCode == 200)
{
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer responseBf = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
responseBf.append(inputLine);
}
in.close();
Logger.sysLog(LogValues.info, this.getClass().getName(),"["+msisdn+"] Response received = "+responseBf.toString());
response = responseBf.toString();
responseBf = null;
if(inNodeDetails.getOperator().equalsIgnoreCase("digicel"))
{
if(response.startsWith("Received"))
{
response = "ok";
}
else if(response.startsWith("{"))
{
// {"id":"185688","status_billing":"INSUFFICIENT_FUNDS","status_sms":"FAILED"}
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Parsing json response.");
Gson gson = new Gson();
JsonResponse jsonResponse = gson.fromJson(response, JsonResponse.class);
if(jsonResponse.getStatus_billing().equalsIgnoreCase("ok") || jsonResponse.getStatus_billing().contains("SUCCESS")){
response="ok";
}
else if(jsonResponse.getStatus_billing().equalsIgnoreCase("INSUFFICIENT_FUNDS"))
{
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Response received for INSUFFICIENT_FUNDS.");
response = "low balance";
}
else if(jsonResponse.getStatus_billing().equalsIgnoreCase("FAILED"))
{
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Failure Response received for some other reason.");
response = "nok";
}
else
{
if(inNodeDetails.getCountry().equalsIgnoreCase("JAM")||inNodeDetails.getCountry().equalsIgnoreCase("HAI")){
response=jsonResponse.getStatus_billing();
}
else{
gson = null;
jsonResponse = null;
}
}
}
else
{
if(inNodeDetails.getCountry().equalsIgnoreCase("HAI") && response.contains("EXCEPTION"))
{
response = "ok";
}
else
{
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"["+msisdn+"] Unknown response.");
response = "nok";
}
}
}
}
else if(responseCode == 502 || responseCode == 500)
{
if(inNodeDetails.getCountry().equalsIgnoreCase("HAI") || inNodeDetails.getCountry().equalsIgnoreCase("JAM"))
{
response = "ok";
}
else
{
response = "nok";
}
}
else
{
response = "nok";
/*Map<String,List<String>> responseMap = con.getHeaderFields();
for (Map.Entry entry : responseMap.entrySet()) {
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "header key = "+entry.getKey() + " value = " + entry.getValue());
}*/
}
return response;
}
catch(SocketTimeoutException ex)
{
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "Read Timeout occurs for msisdn = "+msisdn);
return "ReadTimeout";
}
catch(ConnectTimeoutException ex1)
{
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "ConnectTimeoutException occurs for msisdn = "+msisdn);
return "ConnectionTimeout";
}
catch(ConnectException ex2)
{
Logger.sysLog(LogValues.APP_DEBUG, Utility.class.getName(), "ConnectException occurs for msisdn = "+msisdn);
return "ConnectionTimeout";
}
catch(JsonSyntaxException ex3){
response=null;
return response;
}
catch(MalformedJsonException ex4){
response=null;
return response;
}
catch(Exception e)
{
Logger.sysLog(LogValues.error, this.getClass().getName(),"["+msisdn+"] Internal Error occured"+coreException.GetStack(e));
return response;
}
finally
{
response = null;
url = null;
obj = null;
con.disconnect();
Logger.sysLog(LogValues.APP_DEBUG, this.getClass().getName(),"Calling GC.");
System.gc();
}
//return response;
}
但是,相同的代码 运行 在每秒大约 50 个请求的生产环境中非常好。
当我使用 JVisualVM 和 Sampler 时,我了解到这种方法 "sendHttpGetReq" 需要很长时间和高 CPU 处理。但是从代码中,我找不到代码应该阻止所有 CPU.
的具体原因这是采样器屏幕截图:
请指出可能是什么问题?
我认为 finally 调用的 System.gc() 方法可能会导致问题。 建议您评论 System.gc() 并尝试一下。