ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 과거의 나에게...(와인 검색 서비스 회고)
    Java & Kotlin 2021. 10. 2. 01:39
    반응형

    1) 서론

    이 글은 약 1년 전, 학생 때 만든 "와인 검색 서비스"의 회고(변명) 글입니다. 

     머릿속으로 대략 생각하면서 작성했습니다. 조만간 시간이 나면, 실제로 리팩토링 진행해볼 예정입니다. 저는 이상하게 새로 무언가를 만드는 것보다, 리팩토링을 통해서 더 좋은 코드와 성능 향상에 관심이 많습니다.

     

    당시에 만든 서비스와  글은 아래와 같습니다.

    https://yeon-kr.tistory.com/131?category=868421 

     

    전체적인 내용(변명)은 "그때는 그게 최선이었다. 그것밖에 몰랐다"라고 할 수 있을 듯합니다...

     

    과거의 나야... 제발 무전받아... 그렇게 하는 거 아니야...

    2) 와인 검색 서비스... 패기는 좋았다!

    사용된 기술

    • 스프링 프레임워크 (boot X)
    • JSP + JavaScript
    • MySQL
    • Beautifulsoup, Jsoup

     

    전체 기능 

    • Beautifulsoup을 활용한 여러 사이트 와인 목록 파싱
    • 파싱 목록 게시판 형태로 보여주고, 검색 가능

     

    당시의 고민

    • 파싱 과정에서의 지나친 시간 소요

     

    당시의 해결 방법

     

    여전히 남아있는 심각한 문제

    • 목록 조회 --> 파싱 --> 목록 응답
    • 와인 목록 보는데 30분씩 걸림
    • 당시 API 개념 부족으로 인한 목록 조회 코드에 다 넣어놓음

     


    3) 2021년 현재의 해결 방법 고민

    2021년 10월 현재의 제가 다시 만든다면, 아래처럼 만들 것 같습니다. "칙칙... 형사님... 들리십니까"

    3. 1) 서비스 분리 (schedule / batch 서버)

    기존의 문제점

    • 와인 목록 조회 --> 파싱 및 DB 적재 --> 목록 응답 (하나의 긴 trasaction)
    • 하나의 긴 trasaction으로 인한 응답 시간 지연 및 timeout error 발생

     

    2021년의 해결 방법 고민

    • 와인 목록 조회 API, 파싱 서버 분리 구축
    • 목록 조회 API 호출 시 현재의 DB 목록 응답
    • 파싱 서버는 batch로 예약된 시간에 파싱

    --> 서비스 분리로 인한 사용자 응답 시간 개선

     

    여전한 고민

    batch가 돌지 않을 때 업데이트된 데이터는 어떻게 파싱 해야 할지 의문입니다. 만약 배치 서버가 돌지 않는 시간에 특정 와인이 50% 파격 세일을 한다면, 이때 해당 정보가 없는 것은 사이트 입장에서 큰 손해입니다. 짧게 드는 생각은 트랜잭션을 작게 나누어, 자주 돌리는 게 대안이 될 수도 있을 것 같습니다.

     

    추가적인 고민으로 2개의 서버가 하나의 DB를 바라보고, 동시에 참조가 발생할 수 있는 환경이 옳은 것인가에 대한 의문이 있습니다.

     

    3. 2) 요청/응답 방식 (REST API)

    기존의 문제점

    • 의미 없는 URI 변수 (의도 파악 어려움)
    • 각기 다른 형식의 응답
    • 단순 조회에 POST 사용 (무조건 POST가 좋은 건 줄...)

     

    2021년의 해결 방법 고민

    • REST API 적용으로 해당 URI 자원 나타냄
    • 올바른 HTTP method 사용
    • 공통된 응답 방식 사용 (JSON)
    • 상황에 맞는 status code 사용

     

    개인적으로 REST API 규칙이 절대적인 방법은 아니라고 생각하지만, 서비스를 분리해서 공통된 방식의 요청/응답을 위해서 가장 좋은 방법이라고 생각합니다. 또한 URI만 보더라도 어떤 자원을 필요로 하는지 명확히 알 수 있어서, 프론트엔드와의 협업 시 편리하다고 생각합니다.

     

    3. 3) JavaScript (JSP 제거)

    기존의 문제점

    • 지저분한 JSTL 문법
    • 느린 jQuery
    • 하나의 파일에 HTML, JS, jQuery 혼합

     

    2021년의 해결 방법 고민

    • HTML, JS 파일 분리 (단순 랜더링과 비즈니스 로직의 분리)

    --> 가독성 증가, JS 코드 재활용 가능

     

    개발하는 입장에서는 당연히 분리를 하는 게 관리도 편하고, 명확합니다. 하지만 어떤 성능적 이점이 있는지는 잘 모르겠습니다. 해당 서비스처럼 무겁지 않은 애플리케이션은 그냥 편한 기술을 사용해도 되지 않을까 생각합니다. 다만 추후의 리팩토링 및 협업 가능성을 고려했을 때는 JS를 사용하는 것이 좀 더 유연한 방법이라고 생각합니다.

     

     

    3. 4) SpringBoot + JPA 사용

    기존의 문제점

    • XML 지옥
    • 초기에 필요한 의존성
    • 수동적인 애플리케이션 설정

    --> 불필요한 작업 증가 및 가독성 저하

     

    2021년의 해결 방법 고민

    • 스프링부트 사용
      • starter로 초기의 다양한 의존성 해결 (JUnit 등)
      • JDBC Datasource 등 다양한 설정의 자동화
      • 톰캣 서버 내장
    • JPA 사용
      • 쿼리 메서드 사용으로 빠르게 작성 및 내용 파악 용이
      • ORM으로 인한 DB 테이블과 객체의 불일치 해결
      • 자바 코드 사용 및 IDE 도움 가능

     

    사실 개인적으로는 JPA를 쓰나, MyBatis를 쓰나 큰 의미는 없는 것 같습니다. 해당 서비스에서는 아주 간단한 CRUD만 들어갔기 때문에 쿼리문을 직접 작성하더라도, 딱히 불편함이 없었습니다. 

     

    하지만 그럼에도 불구하고 ORM 하이버네이트의 장점은 크다고 생각합니다. 테이블과 엔티티의 매핑으로 객체지향적으로 쿼리를 다룰 수 있게 됐고, 자바 코드 사용으로 IDE에서 자동완성 및 에러를 미리 검출해줍니다. 이는 개발 방법이 아닌, 생산성 향상에도 큰 도움이 된다고 생각합니다.

     

    또한 XML이 아닌 자바 코드로 설정을 하면 체감상 100배는 편한 듯합니다. 지원되는 애노테이션도 많고, 자바 코드로 작성하다 보니 조금 더 가독성 있고 오타 체크도 잘 됩니다. 생산성 측면과 설정이 늘어나더라도 가독성 측면에서 좋다고 생각합니다. 


    앞서 언급했듯이 이번 글의 요약은 "그때는 그게 최선이었다. 그것밖에 몰랐다" 입니다. 

     

    당시에는 처음으로 CRUD 기능이 들어간 서비스를 만들었었습니다. 그렇다 보니 성능, 안정성에 대한 고민보다는 "돌아만 가는" 코드를 작성하기 바빴습니다. 스프링이 뭔지도 모르고, 일단 만들어 보고 싶었으니까요. 

     

    그러다 보니 "돌아는 가지만", 실제로 서비스를 하기에는 말도 안 되는 부분이 많았습니다. 게시글 한번 보는데, 파싱을 다 돌고 보여주는 것이 대표적 예시입니다. 게시글 한번 보는데, 10분씩 걸리고 했으니까요. 정말 말도 안 됩니다.

     

    그리고 공통적인 기능의 분리 및 모듈화에 대한 개념이 없이 코드들이 스파게티처럼 꼬이고 꼬여, 새로 만드는 게 빠른 수준이 돼버렸고요. 메서드끼리의 chain이 8개씩 되기도 했습니다. 

     

    또한 전체적인 설계 및 구성에 대한 이해도 부족으로, 최대한 정해진 코드를 약간씩 수정하는 방식으로 성능 개선했었습니다. 정해진 코드에서 변경하기 위해 자료구조와 시간 복잡도의 고려를 극단적으로 했습니다. 덕분에 공부가 많이 됐었지만, 처음부터 설계를 잘했고 큰 그림을 봤었더라면 하는 아쉬움이 있습니다.

     

    하지만 이러한 경험 덕분에 무거운 서비스들을 한 곳에 몰아넣는 것보다는, 최대한 모듈화 하여 분리하는 것이 좋다는 것을 느꼈습니다. 특히 이러한 것은 단순히 성능과 안정성 측면뿐만 아니라, 개발자의 생산성과 편리성도 고려되어야 한다고 생각합니다. 

     

    앞으로 서비스를 제작할 때는 설계하는 시간을 더 충분히 가져야 할 것 같고, 이 설계가 언제든지 변경될 수 있다는 마음을 가지고 시작해야 할 것 같습니다.

     

    여러분들은 저처럼, 과거의 본인에게 무전하시는 일이 없기를 바랍니다.

     

    반응형

    댓글

Designed by Tistory.