업무와 관련해서 비지니스 로직 응답 속도 개선을 위해 만든 병렬처리모듈을 소개한다.
아래 모듈을 실무에 적용하여 최대 1/4 정도의 응답 속도 감소 효과를 볼 수 있었다. (4s -> 1s)
1. 개요
- 선후 관계가 없는 비지니스 로직의 처리 응답 속도를 개선하기 위해 자바 concurrency 및 reflection을 이용해 병렬로 처리하는 모듈 개발.
2. 소스 레파지토리 : https://github.com/khparkDev/ParallelExecutor
- 응답을 받을 수 있는 Callback Executor와 응답을 받지 않는 DefaultExecutor 두 클래스로 구분해놓았다.(TestMain.java에 사용 방법을 기술해놓았음)
3. 주요 로직
* 작업 추가 및 실행
protected void executeWorkerThread() { executor = Executors.newFixedThreadPool(taskMap.size()); taskMap.entrySet().parallelStream().forEach( tm -> { futureMap.put(tm.getKey(), executor.submit(new ParallelWorkerThread(taskMap.get(tm.getKey())))); executorLogger.setStartTimeTask(tm.getKey()); }); futureMap.entrySet().parallelStream().forEach( fm -> { try { result.put(fm.getKey(), futureMap.get(fm.getKey()).get(TIMEOUT_SEC, TimeUnit.SECONDS)); executorLogger.setEndTimeTask(fm.getKey()); } catch (Exception e) { LOGGER.error("# executeParallelTask : ", e); } }); }* 실제 작업 수행 쓰레드 클래스
public Object call() throws Exception { Method[] classMethods = classObject.getClass().getDeclaredMethods(); List4. 실행 결과 - 개별 작업들의 실행 시간 출력 및 가장 오래 걸린 시간(실제로 병렬처리가 수행된 시간)을 보여준다methodList = Stream.of(classMethods).parallel() .filter(method -> method.getName().contains(methodName) && method.getParameterTypes().length == taskParamClassType.length) .collect(Collectors.toList()); if (taskParamClassType.length == 0) { return methodList.get(0).invoke(classObject); } for (Method targetMethod : methodList) { Class[] methodParams = targetMethod.getParameterTypes(); for (int i = 0; i < taskParamClassType.length; i++) { String taskParamTypeName = taskParamClassType[i].getSimpleName().toLowerCase(); String methodParamTypeName = methodParams[i].getSimpleName().toLowerCase(); if (taskParamTypeName.contains(methodParamTypeName)) { targetMethod.setAccessible(true); return targetMethod.invoke(classObject, taskParam); } } } return EMTPY_OBJECT; }
[2015-11-09 20:43:02] [DEBUG] TestMain.main[24]
[2015-11-09 20:43:02] [DEBUG] SampleService.testService[34] testService = {true, C, 1, 1}
[2015-11-09 20:43:02] [DEBUG] SampleService.testService[24] testService = {msg = message test!}
[2015-11-09 20:43:02] [DEBUG] SampleService.testService[13] testService
[2015-11-09 20:43:02] [DEBUG] SampleService.testService[29] testService = {10, 12.2,345.123}
[2015-11-09 20:43:02] [DEBUG] SampleService.testService[19] testService = {model.getName() = testName}
[2015-11-09 20:43:02] [DEBUG] ExecutorLogger.prettyPrint[54]
--------------------------------------------------
taskName = testService0 , execute time = 100 ms
taskName = testService2 , execute time = 100 ms
taskName = testService1 , execute time = 140 ms
taskName = testService4 , execute time = 100 ms
taskName = testService3 , execute time = 100 ms
--------------------------------------------------
Total Execute time = 140 ms
--------------------------------------------------