같은 컴퓨터 (이 경우 CentOS)에서 실행 중이지만 다른 Tomcat 서버에 배포 된 일부 응용 프로그램과 연결하는 HttPURLConnection 프로그램이 있습니다. 즉, 두 tomcats가 동일한 시스템에서 실행중인 다른 tomcats에 배포 된 두 응용 프로그램간에 HttpConnection이 만들어집니다.CentOS에서 실행될 때 HttpUrlConnection이
모든 것이 잘 작동하며 하나의 요청을 할 때 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 및 샘플러를 사용할 때 "sendHttpGetReq"메소드가 매우 오랜 시간과 높은 CPU 처리를 수행하고 있다는 것을 알아야합니다. 하지만 코드에서 알 수 있듯이 코드가 모든 CPU를 차단해야하는 구체적인 이유는 찾을 수 없습니다.
이 문제가 될 수있는 것을 제안하십시오 : 여기
는 샘플러 스크린 샷입니까?
프로필러로 확인하십시오. – Kayaman
우리는이 코드를 디버그하여 높은 CPU 사용을 유발하는 부분을 알 수 없습니다. 가서 코드를 프로파일 링하고 프로파일 러에서 병목 현상이 어디에 있는지 알려줄 필요가 있습니다. – nos
@Kayaman 이미 jVisualVM 및 Sampler를 사용했으며이 특정 코드가 많은 CPU 시간을 사용하고 있음을 알았습니다. 질문도 업데이트되었습니다. – KayV