호우동의 개발일지

Today :

article thumbnail

서론

모든 팀들이 본격적으로 프로젝트 개발에 들어갔다.
생각보다 내가 부족한 부분이 많아서 속도가 다른 팀원들만큼 안 나서 마음이 급급했다..

그래서 블로그도 바빠서 잘 못썼다..
원래는 트러블 슈팅이다 뭐 다해서 쓸게 엄청 많은데, 일정에 쫓긴다고..ㅠ

이번 포스팅에서는 주로 지난 3주간 했던 것에 대해 이야기하고,
스파로스를 통해 배웠던 것에 대해 이야기하겠다!

애플 모니터긴 한데 LED임
애플 모니터긴해요

강사님께서 특별히 빌려주신 애플 모니터.. 처음 써봤는데 좋더라..
지금도 감사히 잘 쓰고 있다..!

 


프로젝트 진행


Git Action을 통한 CI/CD 구축

Git Action을 사용한 CI/CD를 구축해 본 경험이 있어서, 우리 팀에서는 내가 인프라를 담당하게 됐다.

근데 또 예전에 했던 그대로 할 수 없지 않은가.. 더 발전시키고 싶었다.
그래서 이번에는 파일 변경 감지 기능을 넣어서 배포 최적화를 추가했다.

CI/CD 방식
CI/CD 방식

현재 위와 같은 구조로 배포를 진행하고 있다.

위 그림을 보면, Docker Container를 통해 Redis와 Spring 컨테이너 2개를 돌리고 있다.
이런 식으로 변경된 컨테이너만 새롭게 도커 허브에 올리고, 내려받는 방식을 사용했다..

너무 힘들었어요.
너무 힘들었어요.

이 녹색불을 완성한다고 3~4일은 태운 것 같다.

잘 동작한다~~
잘 동작한다~~

그래도 레퍼지토리에 내가 만든 Git Action이 돌아가는 걸 볼 때마다 기분은 좋더라..ㅎ


Query DSL을 이용한 검색 구현

이번에 처음으로 Query DSL을 사용해 봤다.
내가 보는 강의에서 Query DSL가 제일 마지막에 있길래, 엄청 어렵겠구나 싶었다.

근데 막상 해보니까 Query DSL은 직관적으로 잘 만들어져 있었다.
DB를 공부했다면 Query DSL은 무난하게 잘 사용할 수 있을 것 같다.

검색 기능을 구현하면서 DB 공부를 더 많이 하게 된 것 같다.
검색 기능에서 고민을 가장 많이 한 부분이 최적화였다.
어떻게 하면 쿼리를 덜 날리고, 응답시간을 최소화할지를 고민했다.

내가 찾은 해답은 DTO를 적극적으로 이용하자였다.
DTO를 이용하여 모든 엔티티를 가져오는 게 아닌,
특정 필드만 가져오는 것만으로도 최적화가 된다는 것을 깨달았다.

private List<SearchProductDto> getSearchProductIds(String keyword, Pageable pageable,
        QCategoryProduct categoryProduct, QProduct product, QCategory category) {

        return jpaQueryFactory
            .select(Projections.constructor(
                SearchProductDto.class, product.id))
            .from(categoryProduct)
            .innerJoin(categoryProduct.product, product)
            .innerJoin(categoryProduct.category, category)
            .where(validateContainsKeyword(keyword, product, category))
            .orderBy(product.id.desc())
            .distinct()
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            .fetch();
    }

내 나름대로 최적화를 위해 노력했다.
offset을 쓰지 않고 인덱싱 된 테이블을 쓰면 훨씬 빠르다는 걸 알지만..
검색 기능에 모든 걸 투자할 순 없다..

나중에 시간이 남으면 더 최적화하도록 하자

 


카테고리 조회(계층형 DB)

우리 카테고리 DB는 자기 참조형 테이블이다.

우리 카테고리 테이블 구조
우리 카테고리 테이블 구조

카테고리별 조회 쉽다고 생각했는데,
대분류 카테고리로 조회해도 관련된 모든 소분류가 나와야 하니까..

생각할 부분이 많아졌다..

private BooleanExpression validateChildCategory(QCategory category, Long categoryId) {
        return category.parent.parent.id.eq(categoryId)
            .or(category.parent.id.eq(categoryId))
            .or(category.id.eq(categoryId));
    }

지금은 parent.parent.id 이런 식으로 주먹구구 식으로 해놨는데..
너무 거슬린다. 코드 예쁘게 바꾸고 싶다. 최적화하고 싶다.

근데 일단 시간 안에 완성해야 하니까 이 부분도 나중에 리팩토링 하도록 하자..


데이터베이스에 데이터 넣기…

현타가 많이 왔던 부분..
가장 기본적인 상품 테이블과 카테고리 테이블을 만드는 것만 해도 정신이 나갈뻔했다.

이게 1200개 ㅋㅋㅋㅋㅋㅋㅋㅋ
이런 식으로 1200개 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

모든 팀들이 파트를 나눠서 200개 정도? 모아서 1200개가량의 상품이 모였다.
근데 이걸 카테고리와 외래키 매핑을 해주는 게.. 미친 짓이었다.

외래키 매핑은 아무리 찾아봐도 DB 툴을 이용해도 자동화가 안되더라..

엑셀.
엑셀.

결국 순수 입력하다가, 도저히 안 되겠어서 엑셀 함수를 익혀서 자동화했다.
내가 진짜 이거 때문에 엑셀 함수를 공부할 줄은 몰랐지..

카테고리까진 어떻게 넣었는데, 옵션은 이제 어떡하지…
데이터 넣는 건 진짜 현타 옴..

 


마무리

요 3주간에는 CI/CD 작업과 더불어서,
ERD 변경, API 명세서 변경, 개인적인 이슈 등에 의해 순수 개발을 많이 하지 못한 것 같다.

그래도 트러블 슈팅 관련은 많이 작성한 듯? 이거 나중에 다 포스팅으로 작성해야지!
도움이 될 거다. 다음 주부터는 매주 작성하자..