이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다. 장애 대비용 서버 증설 여부를 결정하기 위해 작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다. 초당 최대 처리량은 요청의 응답 완료 여부에 관계없이 임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다.
HashMap<Integer,Integer> seconds = new HashMap<Integer,Integer>(); String[] tmp = new String[3]; SimpleDateFormat transFormat = new SimpleDateFormat("HH:mm:ss.SSS"); try{ for(String line : lines){ tmp = line.split(" "); String tmpDateStr = tmp[1]; String tmpDur = tmp[2].replace("s", ""); int tmpDurInt = (int) Double.parseDouble(tmpDur) * 1000; // Str > Date Date tmpDate = transFormat.parse(tmpDateStr);
// Date + Duration int plusTmpInt = (int)tmpDate.getTime() + tmpDurInt; //초는 getTime을 한값의 1000으로 나눈 수이기 떄문에 계산 int StarTime = (int) tmpDate.getTime()/1000; int EndTime = plusTmpInt/1000;
for(int i = StarTime; i <= EndTime ; i++){ // 해당 Duration(기간 초단위) + 1 씩 해줘야함 seconds.put(i, seconds.getOrDefault(i, 0) + 1); } } } catch(Exception e){ System.out.println(e.getMessage()); } int max = 0; for(int key : seconds.keySet()){ if(max < seconds.get(key)){ max = seconds.get(key); } }
return max; } }
1차시도 후 많은 테스트 케이스에서 실패하였다.
테스트 1 〉 실패 (39.45ms, 87.9MB) 테스트 2 〉 실패 (80.26ms, 88.2MB) 테스트 3 〉 실패 (59.44ms, 91.4MB) 테스트 7 〉 실패 (80.47ms, 90.7MB) 테스트 10 〉 실패 (31.42ms, 79.5MB) 테스트 12 〉 실패 (61.48ms, 84.5MB) 테스트 15 〉 실패 (23.44ms, 81.6MB) 테스트 18 〉 실패 (53.90ms, 101MB)
1초 단위로 끊는게 아니고 1초에 범위에서 가장많은 요청이 있는 내역을 찾는거니 해당 Duration내의 요청을 lines 개수만큼 반복해서 Max 값을 구하는 방식으로 바꿔야하는 것을 파악했다. HashMap -> line 배열로 변경
classSolution{ publicintsolution(String[] lines){ String[] tmp = new String[3]; SimpleDateFormat transFormat = new SimpleDateFormat("HH:mm:ss.SSS"); Date[] endDate = new Date[lines.length]; Date[] startDate = new Date[lines.length]; int max = 0; try{ for(int i = 0; i < lines.length ;i++){ tmp = lines[i].split(" "); String tmpDateStr = tmp[1]; String tmpDur = tmp[2].replace("s", ""); int tmpDurInt = (int) (Double.parseDouble(tmpDur) * -1000); endDate[i] = transFormat.parse(tmpDateStr); startDate[i] = addTime(endDate[i], tmpDurInt + 1); } } catch(Exception e){ System.out.println(e.getMessage()); } for(int i = 0; i < endDate.length; i++) { int maxTemp = 0; long endTimeMilliI = endDate[i].getTime(); long finTimeMilli = addTime(endDate[i], 1000).getTime(); for(int j = 0; j < startDate.length; j++) { long startTimeMilli = startDate[j].getTime(); long endTimeMilliJ = endDate[j].getTime(); if((finTimeMilli - startTimeMilli) <= 0) { continue; } if(((endTimeMilliI - startTimeMilli) <= 0 && (finTimeMilli - startTimeMilli) > 0) || ((endTimeMilliI - endTimeMilliJ) <= 0 && (finTimeMilli - endTimeMilliJ) > 0) || ((endTimeMilliI - startTimeMilli) > 0 && (endTimeMilliI - endTimeMilliJ) <= 0)) { maxTemp++; } } max = Math.max(max, maxTemp); } return max; }
public Date addTime(Date date, int tmpDurInt){ Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MILLISECOND, tmpDurInt); return c.getTime(); } }