업무와 관련해서 비지니스 로직 응답 속도 개선을 위해 만든 병렬처리모듈을 소개한다.
아래 모듈을 실무에 적용하여 최대 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();
	List 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;
}
4. 실행 결과 - 개별 작업들의 실행 시간 출력 및 가장 오래 걸린 시간(실제로 병렬처리가 수행된 시간)을 보여준다

[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
--------------------------------------------------

+ Recent posts