2007년 07월 25일
OGNL Performance
서비스 오픈을 며칠 앞두고 성능 측정을 했습니다. 똑같은 페이지가 이전 버전에 비해 2배로 느려졌더군요. 페이지에 뿌리는 내용은 거의 같은데 iBatis 쓰고 Struts 1에서WebWork(이제 서야... Struts 2도 아니고 =.=)으로 웹프레임웍을 바꿨습니다. 프로파일링 해보니 DB 접근도 2배 정도 느려졌고, JSP에서는 8배 정도 느려졌고, 본문 내용을 변환하는 곳에서도 2배 정도 느려졌더군요. 일단 본문 내용 변환하는 곳은 정규 표현식을 적게 사용하도록 수정해서 해결. 더 개선 가능한 부분이 있지만 기존 코드를 전혀 이해할 수 없어서 포기. DB 접근은 iBatis resultMap에 javaType, jdbcType 등을 지정해봤는데 효과가 없었습니다. 회사 공식 lousy한 프레임웍도 DB 접근을 중계하는데 우울한 코드가 많아서 걷어 내면 좋겠는데 그건 제 힘만으로는 걷어 낼 수가 없어서 예전에 포기 했고, 캐슁을 하면 DB 부하도 줄고 상당히 빨라질텐데... DB에 접근하는 경로가 다양하고, 조인이 많아 그것도 힘듭니다.
남은 곳은 JSP인데... OGNL 접근이 엄청 느리더군요. 38 단위 시간 정도 걸리던 JSP가 WebWork으로 바꾸고 나서 370 단위 시간 정도 걸렸습니다. 인터넷을 좀 뒤졌더니 OGNL이 느리다고 합니다. 이 문제를 개선한 OGNL이 최근 나왔습니다. 그래도 MVEL보다 느리다 아니다 말이 많은데 어쨌든 2.6.x보다는 빨라졌습니다. struts2에 개선된 ognl이 도입되면 xwork 1.2.3으로 백포팅 예정이었으나 1.2.3 릴리즈는 놓치고 1.2.4에 포함할 계획이더군요. 그러나 서비스 오픈은 며칠 후.
WebWork 소스를 보니 WebWorkRequestWrapper에서 getAttribute가 호출될 경우 request.getAttribute로 먼저 찾아보고 없으면 OGNL을 뒤지더군요. 그래서 일단 주요 액션에서 주요 속성들을 request.setAttribute로 넣어주었습니다. 프로파일링 해보니 효과가 있었습니다. request.setAttribute 해주는 것이 영 찜찜하긴 했지만 효과가 있었습니다. OGNL 개발자의 OGNL Expression Compilation을 보고 새 OGNL을 xwork에 적용해 보려고 했는데 생각보다 쉽지 않았습니다. xwork과 ognl을 좀 알아야 되겠더군요. 그래서 포기.
다음 날 늦잠을 자서 지하철을 타고 출근하는데 Interceptor를 사용해서 리플랙션으로 액션의 getter를 뽑아서 request.setAttribute에 넣어주면 디자인을 해치지 않으면서도 성능을 개선할 수 있겠더군요. 출근해서 해봤는데 IllegalAccessException이 나서 한참을 삽질했는데 public이 아닌 부모 클래스의 public getter를 invoke할 때 에러가 났습니다. 부모 클래스들을 public으로 바꾸고 다시 프로파일링. 처음에는 370 단위 시간 걸리던 JSP가 이제 추가한 Interceptor까지 합쳐서 125 단위 시간 밖에 안 걸립니다. 기존 38 단위 시간에 비하면 3배 이상 느리지만 그래도 선방했습니다. xwork이 새 OGNL을 도입하기 전까지는 그럭 저럭 버틸 수 있는 방법입니다.
이런 시스템적인 부분은 원인만 알면 어렵지 않게 개선할 수 있는데, 진짜 고쳐야할 부분은 어플리케이션 코드죠. 중복과 비효율적인 작업들이 여기 저기 널려 있어 고치기 힘든데 어플리케이션을 고치지 않으면 드라마틱한 향상은 힘들겠죠.
그래도 만세~ 삽질 삽질에 암반에 삽 끝이 무디어질 때 마다 숫돌을 던져 준 동료들에게 항상 행복이 있기를 바랍니다.
남은 곳은 JSP인데... OGNL 접근이 엄청 느리더군요. 38 단위 시간 정도 걸리던 JSP가 WebWork으로 바꾸고 나서 370 단위 시간 정도 걸렸습니다. 인터넷을 좀 뒤졌더니 OGNL이 느리다고 합니다. 이 문제를 개선한 OGNL이 최근 나왔습니다. 그래도 MVEL보다 느리다 아니다 말이 많은데 어쨌든 2.6.x보다는 빨라졌습니다. struts2에 개선된 ognl이 도입되면 xwork 1.2.3으로 백포팅 예정이었으나 1.2.3 릴리즈는 놓치고 1.2.4에 포함할 계획이더군요. 그러나 서비스 오픈은 며칠 후.
WebWork 소스를 보니 WebWorkRequestWrapper에서 getAttribute가 호출될 경우 request.getAttribute로 먼저 찾아보고 없으면 OGNL을 뒤지더군요. 그래서 일단 주요 액션에서 주요 속성들을 request.setAttribute로 넣어주었습니다. 프로파일링 해보니 효과가 있었습니다. request.setAttribute 해주는 것이 영 찜찜하긴 했지만 효과가 있었습니다. OGNL 개발자의 OGNL Expression Compilation을 보고 새 OGNL을 xwork에 적용해 보려고 했는데 생각보다 쉽지 않았습니다. xwork과 ognl을 좀 알아야 되겠더군요. 그래서 포기.
다음 날 늦잠을 자서 지하철을 타고 출근하는데 Interceptor를 사용해서 리플랙션으로 액션의 getter를 뽑아서 request.setAttribute에 넣어주면 디자인을 해치지 않으면서도 성능을 개선할 수 있겠더군요. 출근해서 해봤는데 IllegalAccessException이 나서 한참을 삽질했는데 public이 아닌 부모 클래스의 public getter를 invoke할 때 에러가 났습니다. 부모 클래스들을 public으로 바꾸고 다시 프로파일링. 처음에는 370 단위 시간 걸리던 JSP가 이제 추가한 Interceptor까지 합쳐서 125 단위 시간 밖에 안 걸립니다. 기존 38 단위 시간에 비하면 3배 이상 느리지만 그래도 선방했습니다. xwork이 새 OGNL을 도입하기 전까지는 그럭 저럭 버틸 수 있는 방법입니다.
이런 시스템적인 부분은 원인만 알면 어렵지 않게 개선할 수 있는데, 진짜 고쳐야할 부분은 어플리케이션 코드죠. 중복과 비효율적인 작업들이 여기 저기 널려 있어 고치기 힘든데 어플리케이션을 고치지 않으면 드라마틱한 향상은 힘들겠죠.
그래도 만세~ 삽질 삽질에 암반에 삽 끝이 무디어질 때 마다 숫돌을 던져 준 동료들에게 항상 행복이 있기를 바랍니다.
# by | 2007/07/25 00:09 | 트랙백(2) | 덧글(3)







☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
제목 : OGNL의 퍼포먼스 문제
OGNL은 퍼포먼스에 문제가 있었다.소문으로만 그런줄 알았는데, 실제로 겪고 나니..힘들었다.일단, request에 같은 setAttribute로 해결을 하였다 다음과 같은 코드 를 보면 알겠지만request에 값이 있으면 OGNL의 value stack을 타지 않고 바로 값을 얻는다.webwork같은 경우 action에서 가급적이면 request를 가지지 않게 디자인을 잡았기때문에, 맘에 들지는 않았지만, 다음과 같이 코드를 작성하였다.pro......more
제목 : 소내기의 생각
남의 블로그에 답글달았다! 아 나 왠지 구루가 된기분이야~~~~~((틀렸으면 어떻하쥐--;))...more