사이드 프로젝트/Beacon프로젝트

[Beacon] 프로젝트 한달 차 회고

EVO. 2023. 9. 11. 01:03

백엔드 2, 프론트 1 이서 모여진 이 프로젝트는 공개 SW 개발자 대회에 참가라는 명목으로 동기부여를 주고 사실 협업 프로젝트는 나에게는 처음이라 공부하는 겸 시작된 프로젝트이다. 

 

먼저 진행된 프로젝트는 https://github.com/Beacon-2023/Beacon-backend 링크에서 볼 수 있고 진행은 한달안에 어느정도 완성된 프로젝트를 제출해야 하기에 스크럼으로 6주간의 스프린트로 진행했다. 해당 내용은 이 https://github.com/orgs/Beacon-2023/projects?query=is%3Aopen 링크에서 볼 수 있다

 

이번 회고글은 자랑하고 싶은 건 전혀 없고 (자랑할 거리가 없다;) 앞으로 해당 프로젝트를 혼자서라도 계속 진행할 수 있을 지 또는 여기서 그만둬야 할지 방향을 다시 잡는 겸 막 작성한 것이니 이 글을 아무도 안봤으면 좋겠다.

 

해결해야 할 이슈

일단은 마감일 약 이틀전 배포를 하면서 그때 알아차렸던 이슈들이 있는데 이들을 간략하게 정리해보면 다음과 같다

여기 https://github.com/Beacon-2023/Beacon-backend/issues/66 에도 정리를 했지만 다시 적어보면

  • 긴 텍스트 저장되지 않은 이슈
    기본가이드라인은 재난안전포탈사이트에서 나온 가이드라인을 그대로 복사하고 db에 저장하고 있다
    (출처만 밝히고 수익성목적으로만 쓰지 않으면 상관 없다니 그렇게 했다)
    여기서 생겼던 문제는 Entity에서 @Lob로 작성을 하면 디비에 테이블이 생성될때 데이터 타입이 TinyText로 db쿼리가 나가고 결국 csv파일로 만든 긴 텍스트를 집어넣을 수 없다. 따라서  다시 DataType을 mediumText로 더 긴 바이트를 저장할 수 있게 한다음 csv파일을 집어넣어야 하는 귀찮은 행위를 해야한다. 물론 실제 서버에서는 jpa로 테이블 생성을 하면 안되고 직접 쿼리로 생성하는것이기 때문에 상관없지만 테스트 서버에서 이런 부분은 해결이 필요해보인다.
  • 로그파일 관리 이슈
    저번에 로그로 관리를 하겠다고 마음먹고 정리한 글이 있다. 실제로 로그파일로 관리하니 서버를 내렸다 올렸다 하는 번거로움은 사라졌지만 Error로그가 잔뜩 쌓여서 aws ec2 프리티어에서 제공해주는 30GB를 넘칠까봐 비용걱정을 계속 했다. 또한 백업 로그파일이 생성도 안되고 그냥 파일 하나로만 관리되고 있는 것 같다. 다시 로그 부분을 리펙토링 해야할 필요가 있으며 로그에서 찍히는 시간이 실제 우리나라 시간과 다르게 찍히는 문제도 있다. 
    따라서 AWS 대신 오라클에서 제공해주는 무료서버로 교체를 하던지 좀 다시 공부해야 할 필요가 있어보인다.
  • 민방위 대피소에서 생긴 UnsupportedOperationException 
    로컬서버에서는 생기지 않았던 예외가 이상하게 실제서버에서 돌리면 생기는 문제이다. 스크래핑하는 과정에서 DB에 저장할 때 생기고 있는 것 같은데 해결할 필요가 있다.
  • 로직 문제
    disaster_alert 테이블에 약 3초에 10개~30개 정도의 행이 계속 쌓이는 문제가 있는데 로직을 다시보고 다른 방법으로 해결해야 할 필요가 있다. 현재 이거 때문에 비용문제가 생길까봐 swagger 라이브 서버를 계속 열어둘 수가 없다.

 

여기까지가 지금 생긴 이슈이고 앞으로 뭘 더 해야할지 정리하기 이전에 그 한달동안 기술적으로 경험한 게 있었나 한번 정리해보려한다

기술적으로 배운 것(?)

사실 기술적으로 배웠다기 보다는 기초를 다지는 순간이었던 기억이었다. 

객체지향적인 설계 

  • dto와 entity간 변환을 mapper 객체로 코드를 따로 빼기
    처음에는 Service단에 넣어서 변환코드를 작성했지만 비즈니스 로직을 수행하는 부분에서 DTO와 Entity를 변환하는 것은 각 패키지마다 공통적으로 존재하는 부분이였고 팀원이 하는 것처럼 Mapper클래스로 따로 빼니 훨씬 깔끔하고 관리하기도 편했다.  

  • 자바 8에서 제공하는 문법 사용
    항상 if문으로 null값인지 체크하는 비효율적인 코드를 작성했는데 Optional문법을 사용하면서 좀 더 코드가 깔끔해졌다.
    또한 람다식을 적극 활용해 기존에 쓰던 반복문과 조건문을 제거하고 예외처리도 UnCheckedException으로 할 수 있도록 커스텀 마이징하여 예외처리도 제거했다. 이전에 약 10줄 넘게 작성했던 코드줄을 단 4줄로 줄이고 오히려 가독성도 높아졌다.

  • LoginRequired 커스텀 어노테이션 생성
    https://github.com/Beacon-2023/Beacon-backend/blob/develop/src/main/java/com/BEACON/beacon/global/interceptor/LoginInterceptor.java 에서 좀 더 자세히 볼 수 있다. 

    이부분은 다른 프로젝트 코드를 보면서 배운 내용이다. HandlerInterceptor 를 상속 받으면 그중 preHandle 메서드가 있는데 이는 http통신으로 컨트롤러에게 응답받기 이전에 먼저 수행하는 행위를 정의할 수 있다. 여기에 LoginRequired 어노테이션을 붙인 메서드에게 세션을 검사하여 로그인을 했는 지 확인하는 로직을 추가하였다. 또한 이 상속받은 클래스를 스프링부트에서 관리할 수 있도록 WebConfig 클래스에 등록하였다. 

    이렇게 함으로써 로그인 절차가 필요한 api엔드포인트에 똑같은 로그인 확인 중복을 없애고 단지 어노테이션을 붙이는 것만으로도 확인이 가능하다.

JPA 공부

  • 엔티티에 Setter 제거
    이에 대한 고민은 https://velog.io/@backfox/setter-쓰지-말라고만-하고-가버리면-어떡해요 에서 많은 해결이 되었고 실제로 이번 프로젝트에 코드에는 Setter 어노테이션은 절대 붙이지 않았다. 그리고 연관관계 편의 메서드를 정의할때만 직접 메소드를 만들었다.
     
  • 연관관계 편의 메서드 사용
    JPA를 이번 프로젝트에 처음 쓰면서 "양방향 매핑할때 연관관계 주인을 잘 정해야 되고 실수가 많다"라는 영한님의 강의를 보고 나는 실수를 안하겠지 라고 생각했지만 막상 프로젝트에서 그걸 고려안하다가 왜 DB에 연관관계가 맺어지지 않지 라는 실수를 범했다 확실히 이때 느낀 것은 직접 써본게 아니면 무조건 실수를 하는 구나 라는 것이다.. 사실 이 프로젝트 말고 과제 테스트에서 실수를 하고 여기서는 제대로 사용을 했다.

    예를들어 회원과 커스텀가이드라인은 일대다 매핑을 이루고 있고 "다"가 연관관계주인으로 설정을 했다(물어보니 보통은 "일"에 연관관계 주인인 경우는 없다고 한다. 그럴경우에는 보통 DB설계가 잘못된거라 한다) 어쨌든 회원에서도 커스텀가이드라인을 보는 일이 있으니 양방향 매핑으로 만들어주고 커스텀 가이드라인을 생성할때 만든 회원과 커스텀가이드라인을 DB에 잘 매핑해서 저장할 수 있도록 연관관계 편의 메서드를 사용하였다. 

위에는 CustomGuideLine Entity 아래는 Member Entity의 메서드

   최근에
https://www.youtube.com/watch?v=brE0tYOV9jQ&t=293s&ab_channel=%EB%B0%B1%EA%B8%B0%EC%84%A0 

영상을 본적 있는데 다행히 백기선님의 질문에 정확하진 않지만 얼추 답을 맞혔고 내가 이해했던 내용과 똑같이 설명하셨다. 다행히 잘 이해를 한 듯 하다. 

  • JPA에서의 N+1 문제
    이 부분은 아쉽게도 제대로 겪지 못했다. 아직도 나는 N+1문제는 lazy loading 기법으로 사용하면 안전하다 이렇게만 이해하고 있는 상태이다. https://www.youtube.com/watch?v=rYj8PLIE6-k&t=1629s&ab_channel=NHNCloud 하지만 이 영상을 보면 그렇게 이해하고 있으면 안되는 것 같다. 아무튼 프로젝트를 더 진행해봐야 더 깊이 공부할 수 있을 것 같다. 

 

 

새롭게 배운 것

  • 로그파일 생성 
    API를 작성이 끝나고 서버에 배포를 했다. 프론트는 이 API를 테스트를 했는데 5xx가 날라왔지만 그 당시에 로그파일이 존재하지 않아서 jar파일을 java -jar ~~~로 직접 실행을 하고 프론트에서 똑같은 시뮬레이션을 돌려서 에러를 확인했던 적이 있었다. 서버를 올리고 내리는 귀찮은 작업으로 로그에 대해 공부를 하고 https://babgeuleus.tistory.com/94 로그파일을 생성했다. 전보다 로그파일만 열면돼서 error로그를 쉽게 볼 수 있다. 하지만 앞에 이슈부분을 해결해야할 필요성이 있다.
  • 서버 배포
    한번도 서버를 배포해본적이 없었는데 이번 기회를 통해 AWS EC2 와 RDS로 배포를 해보았다. 확실히 배포를 해보니 느낀 점은 이론으로만 배웠던 거랑 달리 장애물을 많이 마주했다. 예를 들면 프리티어는 RAM이 1GB라 배포 자동화를 할 수 없어서 CI/CD가 불가능한 점 그리고 로컬서버에서는 잘 돌아가던게 실제 배포서버에서는 새로운 예외가 발생한다는 점 DB에 지속적으로 마구 쌓이는 데이터 때문에 비용관리를 해야한다는 점 이것저것 문제가 속출한다. 앞으로 좀 혼자 간단한 토이프로젝트로 서버를 배포해보고 이것저것 실험좀 해보면서 익숙해져야 할 필요성이 느껴졌고 AWS말고도 서버를 지원해주는 오라클 등이 존재한다는 것을 알게 되었다. 아마 이번에 오라클로 교체해볼 생각이다.
  • Swagger API Document 생성
    팀원 덕분에 굉장히 많은 것을 배울 수 있었다. 서버부터 API까지 팀원이 한 번 경험해 본 덕분에 이번 기회에 나는 새롭게 배울 수 있어서 감사를 전하고 싶다. 처음엔 프론트와 백엔드가 API를 정하기 위해서 팀원과 공유를 위해 나는 먼저 yaml파일로 swagger를 작성했다. https://app.swaggerhub.com/apis-docs/MAZINGER97/Beacon_API/1.0.0 에서 볼 수 있다.

    지금 생각해보니 왜 하루를 버리면서 이 코드를 작성했는지 잘 모르겠다. 물론 나중에 실제 Swagger API를 작성했을 때 많은 도움이 되었지만 시간대비효율이 잘 안나왔던 작업이었던 것 같다. 다음에는 노션같은 문서로 간단하게 작성하는게 더 낫고 팀원도 API문서를 수정하는데 더 효율적일 것이라 생각된 부분이었다. 

    아무튼 라이브 서버도 역시 작성을 해서 마무리를 지었다. 

더 다양한 내용하게 고민한 내용들은 
https://luck-hurricane-634.notion.site/15f2fe4566944a7c947f0eff5a2b672e?pvs=4 에서 볼 수 있다.

 

앞으로 해결해야 할 문제 

 

더 있는데 쓸수록 벽이 점점 커지는 기분이 들어 일단 이것을 최우선으로 해결해보겠다.

그리고 막상 글을 써보니 역시나 내 수준은 너무나도 기초적이다. Spring을 쓰고 있다지만 그냥 SpringBoot에 의존해서 편하게 개발을 하고 있는 느낌이 든다. 그래도 이번 프로젝트를 통해 기초적으로 배운게 많았고 예전보다 좀 더 성장을 한 느낌이 든다. 이 방향대로 더 차근차근 진행하면서 정리해야 할 필요가 있어보인다.