요약
몇 년전 서울 강서구 소재 아웃바운드 영업 업체에서 요청이 있어 작업한 내용입니다.
자체 직원으로 상담원분들이 계시고 업체에서 영업 의뢰가 들어오면 주로 소상공인을 대상으로 아웃바운드 영업을 대행 해주는 업체 입니다.
자체로 가지고 있는 소상공인 DB에서 영업이 될 만한 곳을 추려서 영업을 하는 시스템 인데, 한 10년전 구축한 업무 시스템이 있고 전체 50여개의 테이블 중 약 100만건 이상 되는 테이블 2개 정도 존재하는 상황이었습니다.
구축 당시 NT Server, MS-SQL 기반에 Java 8 + Struts, Spring, iBatis 로 구현되어 있는 시스템입니다.
자체 사무실에 고정IP로 NT Server, MS-SQL을 한대에 두고 운영하고 있었는데, 라이센스 문제 (라이센스를 보유하고 있는지 없는지도 모름) 및 초기 개발하고 유지보수를 그때 그때 외부 개발자에게 의뢰해서 겨우 끌고 나가고 있는 상황으로, 데이터 100만건 정도는 대용량 이라고 할 수도 없고, 시스템 하드웨어 사양으로 봐도 문제가 없는데, 영업 DB를 조회 하면 풀 텍스트 / 풀 스캔 검색으로 수행하고 조회 하면 100만건 중 데이터 한두건 나오는데 1~2분씩 걸리고 일주일에도 한두번 씩 시스템이 다운되어 어떤 개발자에게 받은 스크립트를 이용해서 사장님이 직접 콘솔에 접속해서 시스템을 재가동 해야 돌아가는 상황이었습니다.
요청사항에 대해 현실적인 방안을 제시하고, 약 한달간 작업하여 협의 한 대로 잘 마무리 되어 이후 1년 넘게 유지보수를 진행하였습니다.
요구조건
- 라이센스 문제 해결
- 영업 시스템 속도 개선
- 단위 기능 추가
작업내역
- 시스템 Linux (CentOS 7 , MySQL) 기반 으로 마이그레이션
- DB 및 어플리케이션 튜닝
- 추가 개발
- 아웃 바운스 상담시 Do Not Call 연동
- 네이버 지역 검색 소상공인 정보 추가 크롤러
전체 시스템을 다시 구축하고 싶어 하셨으나 기간 및 비용 문제로 위 내용 정도로 한달 정도 기간을 잡고 진행 하기로 협의 하였습니다.
경과
1차 DB 마이그레이션
다행이 소스는 존재하는 상태이고 각종 시스템 계정도 관리는 되고 있는 상황이었습니다.
업체와 협의 하여 비슷한 사양의 중고 1U 서버를 추가로 넣고 CentOS 설치, 1차 DB 마이그레이션을 진행 했습니다.
테이블이 약 50여개 되었는데 주요 테이블간 릴레이션이 존재 하는 상황으로 릴레이션 관계를 파악하여 ER-D 작성 하여 우선 순위를 파악하여 진행했습니다.
MS-SQL -> MySQL 간 컬럼 속성 등을 고려하여 분석 하고 스크립트 작성하는 시간 2~3일 제외하고 실제 마이그레이션 시간은 약 2시간 정도 소요 되었습니다.
어플리케이션 튜닝
1. J2EE -> Jakarta EE 변경
기존 Java 8 로 구축된 시스템을 Java 17로 올리면서 발생하는 중요한 문제가 있습니다.
J2EE에는 Java 웹 어플리케이션의 기본이 되는 javax.servlet 같은 관련 패키지가 있습니다.
Java 11 이상으로 적용하기 위해서는 J2EE를 더이상 사용하지 못하고 Jakarta EE로 변경해야 합니다.
간단히 말하면 관련 라이브러리리들을 변경하고 소스 상에서 javax.~ 으로 되어 있는 것을 모두 jakarta.~ 으로 변경해야 합니다.
J2EE의 역사
J2EE(Java 2 Platform, Enterprise Edition)는 자바를 최초에 만든 썬마이크로시스템즈에서 제시한 스펙으로 이름에서도 볼 수 있듯 기업용 플랫폼을 지향합니다.
javax.* 로 시작하는 패키지명
- Web Tier
Servlet, JSP, JSTL 등이 포함되어 있습니다.
- Business Tier
EJB(Enterprise Java Beans), JTA(Java Transation API), JMS(Java Message Service) 등으로 구성되어 있습니다.
- 기타 JDBC, JCA 등의 스펙이 포함되어 있습니다.
썬마이크로시스템이 오라클에 인수 되면서 Java의 라이센스를 오라클에서 인수하고 이후 Java, J2EE 의 스펙을 오라클에서 관장해 왔습니다.
J2EE 발표 후 뜨거웠던 EJB 시장이 구축 유지보수 비용, 성능 등의 문제로 2000 초반 Business Tier 의 인기가 시들해 졌고, Struts, Spring 등 웹티어만을 이용한 Servlet, JSP Model 2 (MVC) 등의 프레임워크와 방법론이 등장하면서 급격하게 사라져 갔습니다.
J2EE 를 가동 할 수 있는 WAS (Web Application Server) 의 가격이 상상을 초월 하면서 초창기 오픈소스로 제공된 JServ + GNU JSP와 이후 등장한 아파치 재단의 Jakarta Tomcat 의 등장은 무료라는 매력과 간단한 설정, 가벼운 성능으로 많은 개발자들의 관심을 가지게 하였으며 2000대 이후 Tomcat + Struts/Spring 의 조합으로 급격하게 이동하게 되었습니다.
이후 Java Web Application 은 Spring 쪽으로 급격하게 기울고 EJB 시장이 급격히 사라지면서 오라클에서도 선한 의지인지? 사업성이 없다고 판단한 것인지? 2017년 Eclipse Foundation에 기부 하였습니다.
이후 오라클에서 Java 상표를 쓰지 말라는 요청으로 Java Enterprise Edtion 에서 Jakarta Enterprise Edition으로 바뀌게 되었습니다.
이로 인해 패키지 명도 javax.* 에서 jakarta.* 로 변경되었습니다.
추가로 이에 따른 종속성 라이브러리들 버전 업그레이드도 필요하므로 상당히 부담가는 작업이지만, 생각보다 어렵지는 않았습니다.
2. DB 어플리케이션 튜닝
대부분 개발자들이 직접 Entity 를 설계하고 SQL을 직접 작성하는 경우 성능에 대해 충분히 고려해 해서 개발 하더라도, 개발 당시에 샘플데이터 만으로 향후 성능까지 고려하지 못하는 경우가 많습니다. 운영하면서 데이터가 쌓이고 성능이 느려지기 시작하는 적절한 시점에 테이블에 맞도록 SQL, Application을 튜닝 해주는 것이 필요합니다.
지속적으로 관리되지 않은 시스템은 내부적으로 발생하는 수많은 Exception, 오래된 프레임워크의 한계, 개발 당시 개발자의 부족한 지식으로 개발된 수많은 구멍들이 존재하고, 방대한 소스를 찾아 가면서 튜닝하는 것은 매우 어려운 작업입니다.
APM(Application Performance Management) 솔루션이 반드시 필요 합니다. 국산 오픈 소스인 Scouter APM을 적용하였습니다.
Scouter APM 은 LG CNS의 전신인 LG EDS 시절 자체 개발된 APM 솔루션에 기반을 둔 것으로 알고 있습니다. 이후 개인적으론 국산 소프트웨어의 최고봉이라고 할 수 있는 Jennifer APM에 지대한 영향을 미친 것 으로 추정하고, 이후 네이버 Pinpoint 에도 많은 영향을 미친 것 같습니다.
현재는 완전히 오픈소스로 변경되어 네이버측 개발자분들로 추정되는 분들이 관리를 하는 것 같은데 최근에는 관리가 잘 되지 않은 것 같아서 안타깝습니다.
Scouter APM 은 콜렉터, 에이전트, 클라이언드로 나뉘어 있는데, 에이전트와 클라이언트는 최근 Java 버전에 맞게 업그레이드 되었지만 콜렉터 역활을 하는 서버는 Java 8 까지만 지원하고 있습니다.
Git 에서 소스를 내려 받아 보면, 어플리케이션 특성상 Java 8 이후 보안 문제 등으로 더 이상 사용할 수 없는 패키지들이 다수 포함되어 있기 때문에 업그레이드를 하지 못하는 것으로 추정하고 있습니다.
Java 8 이상의 어플리케이션에서 사용하기 위해서는, 구동하는 어플리케이션에 맞는 에이전트와 로컬 환경에 맞는 클라이언트를 설치하고, 서버는 별도로 Java 8설치해서 가동해야 합니다.
그럼에도 충분히 운용할 만한 솔루션으로 어플리케이션의 병목지점, 장애포인트 모니터링 및 시스템 알람 기능이 매우 뛰어납니다.
더 자세한 내용은 아래 깃허브와 포럼을 참고 하시기 바랍니다.
튜닝 포인트는
- 인덱스 생성 : 주요 검색어 대한 컬럼에 인덱스 생성
- 검색 조건 개선 : 업무에 영향이 없는 선에서 풀 텍스트 검색의 범위를 줄일 수 있도록 검색조건 추가 (예를 들면 인덱스가 있는 지역 컬럼을 먼저 선택하고 풀텍스트 검색 하는등)
- 공통 페이징 쿼리 개선 : 항상 테이블 풀 스캔을 할 수 밖에 없도록 구현되어 모든 리스팅 쿼리에 적용되어 있는 쿼리를 풀스캔을 하지 않도록 수정
- 통계 테이블 추가 : 통계 레포트 전용 테이블 생성해서 일단위 집계 하도록 배치 처리
- 어플리케이션 구종 중 발생하는 Exception 모두 처리
이정도 만으로 검색어 입력 후 1~2분씩 멍때리고 있어야 하는 상황을 모든 페이지에서 1초 이내에 결과가 나오고, 시스템이 다운되지 않도록 수정할 수 있었습니다.
수년간 답답함을 느끼며 사용하던 담당자 들은 신기해 하다가 데이터가 일부만 들어간 것 아니냐는 의심의 눈초리까지...
3. 추가 개발건 개발
요구 조건이 명확하지 않아서 애를 먹은 것 외에 특이 사항은 없었습니다.
2차 DB 마이그레이션
약 2주간의 테스트를 마치고 최종 2차 마이그레이션을 진행했습니다.
결론
자체 개발조직이 없는 작은 기업에서는 필요한 시스템을 구축하기도 어렵고 구축해도 유지보수에 더 많은 어려움을 격는 것 같습니다.
어떻게든 해결해야 하는 상황들이 그때 발생하면 그때 그때 프리랜서 들을 투입해서 응급 처치식으로 처리를 하는 수준이다 보니 시스템 내부를 살펴 보면 그간의 히스토리들이 보이면서 어떻게 안보인다고 이렇게 처리를 하고 봉인해 두었을까? 하는 안타까움을 금할 수가 없습니다.
물론 그때 그때 작업자의 고충도 충분히 이해하면서 내가 만든 시스템이 나중에 누군가가 들여다 보고 같은 안타까운 마음을 느끼지 않도록 신경써야 하겠습니다.
끝.