알고리즘 주차가 끝나고 개인 프로젝트 주차가 시작되었다. 예약 구매 라는 주제를 선택했다. 1주차라 기능 구현 난이도가 그렇게 높진 않았다. 오랜만 ERD 설계하고 코딩하니까 조금 설렜던 거 같다. 그치만 이게 내가 생각해낸 아이디어가 아니라 큰 틀이 정해진 상태에서 그 안을 채워가야하는 거라 조금 어려운 점도 있었다. 추상적이라서 더 힘들었지 않나 생각한다. 그래서 초반에 어려움이 많았지만 매니저님들이 이를 반영해서 좀 더 구체적으로 틀을 잡아주셨다. 그나마 좀 할만해지지 않았나 싶다!
모두가 같은 주제로 같은 어려움을 고민하고 논의하는 과정에서 많이 배우게 되는 것 같다.
그리고 나도 언젠가 꼭 모각코를,,,
1. 이번 주 항해 취업 리부트코스에서 내가 구현한 기능은 무엇인가요?
- 유저 관리 기능
- 마이페이지 기능 (회원 정보 변경, 내가 등록한 상품 조회)
- 상품 관련 기능
- 위시리스트 기능
- 상품 주문 기능
- 배송 기능
- 반품 기능
2. 해당 기능을 구현하기 위해, 어떤 기술적 의사결정을 거쳤나요?
- 고민한 기술의 종류들에는 무엇이 있나요?
- 암호화 방식: jacypt, crypto, aes 알고리즘 사용해 직접 구현
- 위 기술들별로 각각의 장단점이 있다면 무엇인가요?1 Jasypt (Java Simplified Encryption)
• 장점:
• 간단한 API로 암호화/복호화 기능을 쉽게 구현할 수 있음
• Spring 프레임워크와 연동하여 사용할 수 있음
• 다양한 암호화 알고리즘(AES, Blowfish 등)을 지원
• 단점:
• 암호화 키 관리 등 보안 관련 세부 사항을 직접 구현해야 함
• 라이브러리 의존성이 생김
2 Crypto 라이브러리
• 장점:
• 다양한 암호화 알고리즘(AES, RSA, ECC 등)을 제공
• 암호화 키 관리, 난수 생성 등 보안 관련 기능을 제공
• 단점:
• 복잡한 API로 인해 초기 학습 곡선이 높음
• 라이브러리 의존성이 생김
3 AES 알고리즘 직접 구현
• 장점:
• 암호화 과정을 완전히 통제할 수 있음
• 보안성을 높일 수 있음
• 단점:
• 암호화 알고리즘 구현 및 관리에 많은 노력이 필요함
• 잘못된 구현으로 인한 보안 취약점이 발생할 수 있음
3. 이번 주 겪은 트러블 슈팅이 있다면 무엇인가요?
1주차에는 환경 세팅 및 Basic 기능 구현이라 트러블 슈팅이 딱히 없었다.
4. 이번 주 진행된 개인 프로젝트에서 얻은 인사이트는 무엇인가요?
(1) 4월 17일 멘토링
서비스 별로 마이크로 서비스를 구분할 때, 엔티티 간 연관관계는 어떻게 맺으면 좋을지 궁금합니다.
- db 먼저 생성하고 나중에 프로젝트마다 필요한 테이블만 조회하는 방식
- 연관관계 안에서 db끼리 처리되도록, 프로젝트가 세분화 되더라도 필요한 테이블만 가져와서 사용한다.
- 여러 개의 프로젝트가 하나의 db를 보고 있다. 필요한 값만 가져와서 사용해라
- 여러 개의 db를 사용하더라도 프로젝트랑 db는 분리되어있다.
- 게시판 프로젝트에서는 user table을 어쨌든 만들어놔야한다.
- 필요한 연관관계를 가져와서 사용하도록 해라
- 결론 : db, 프로젝트 분리해라
- db 설계할 때는 msa를 고려할 필요가 없다.
- 코드상 그런거고 db는 하나로 되어있다. 어떤 식으로 가져올지는 개발하면서 고려하면 됨
백엔드 프로젝트 - 프론트를 가장 쉽게 만드는 방법 ?
- 타임리프, 미리 만들어진 템플릿 사용하기
- 가장 좋은 건 프론트 섭외
- restapi 설계 할 때 프론트 입장까지 고려할 수 있다. (한번쯤은 프론트 경험해보는 것도 좋다.)
상품에 대한 재고를 상품 테이블과 상품 재고 테이블로 별도로 구분해야 할지 궁금합니다.
- 굳이 나눌 필요는 없다. 언제 바꼈는지 로그 파일로 알고 있으면 될 듯
- 언제 추가됐는지, 언제 제거됐는데
- 따로 분리해서 테이블 생성해도 필드에 재고 밖에 없어서 조인만 계속 될 것 같음
프로젝트 구현 사항이 추상적이라 erd 설계가 어렵습니다.
- 명확한 것만 먼저 구현하고 이후에 추가하는 걸로
- 구글 시트 내용 보지 말고 프로젝트 가이드라인 > 백엔드 1주차 과제 노션 페이지 보고 erd 작성하기
처음부터 MSA를 구성해서 환경을 구성하는 게 좋을지 궁금합니다.
- msa를 설계를 완벽하게 하고 시작하는 건 어려움
- 명확하게 역할이 나눠지는 게 보이면 그것부터 나눠라
- 프로젝트 가이드라인 보고 맞춰서 가면 될 듯
마이크로서비스를 어떤 기준으로 나누면 좋을지 고민입니다.
- 명확하게 성격이 다르다 - 그 기준으로 하면 됨
- 해보면 별거아님 …케케
- 프로젝트를 그냥 나누는 개념일 뿐 지금은 크게 신경쓰지 말고 erd, api 설계부터 하고 나서 어떻게 나눠지겠다가 보이면 그것부터 나눠보기
ETC
- varchar 사이즈를 필드 특성에 맞춰서 조절해라
- 좀 더 적합한 타입이 있는지 고민해보기
- erd 설계 시 연관관계 고려
- 식별관계가 유리한 경우
- 외래키 아니고 필드로 키값을 가지고 있는 것
- flowchart → https://whimsical.com/
- sql - 웬만하면 대문자/소문자, 들여쓰기 일관성있게
- 자바 개발자 - 자료형에 민감해야한다.
- 조금 더 신경쓰기
- 연관관계 사이클이 문제가 될지? → 시각화 해봐라, 사이클이 아닐 수도 있다.
- 외래키 매핑을 어떻게 했는지가 중요함
- 예를 들어 두개의 테이블이 서로의 pk를 갖고 있다? → 문제됨
(2) 4월 19일 멘토링
회원가입 로직
restful → stateless 이메일 인증도 api 호출해야한다. 결론: 회원가입 api, 이메일 전송 api, 이메일 인증 코드 확인 api -> 세가지로 나눠서 진행하면 된다.
이메일 암호화 → 이메일 중복 검증 과정
똑같이 나오는 걸로 적용하면 됨
db에서 모든 사용자를 조회해서 비교하는 건 너무 비효율적!
보안상 이슈는 지금 프로젝트 단계에서 고려하지 않아도 될 듯하다.
다른 방법으로 우회해서 보안성을 보장하도록 하면 됨
패키지 구조
회사마다 다르긴 함
layer 별 or domain 별
msa 환경 공통 코드
공통된 코드를 관리하는 모듈이 있어서 이걸 import 받아서 할 수 있다.
검색 키워드 : 공통 모듈
로그아웃 처리
jwt토큰 만료기간이 있어서 따로 관리 해주지 않아도 되는데
로그아웃하는 시점에서 jwt토큰 사용 못 하게 하고 싶다면
예를 들어 블랙리스트처럼 관리하면 된다.
이미 발급된 토큰을 (만료기간 안 지난 경우) 그 토큰으로 api요청이 오면 “이미 로그아웃된 토큰입니다” 응답
(3) 4월 20일 멘토링
- jwt token : 서버 입장에서 stateless
- 상태(데이터)를 jwt가 가지고 있음 (Jwt.io에서 확인 가능)
- 보안이 중요할 수록 세션을 사용하는 게 맞다.
- 쿼리를 해야한다면 세션을 사용해야한다.
- jwt를 stateless 하게 사용하는 게 맞다.
- 추가 질문 - 요구사항 충족하려면 로그인 기록을 모두 저장해야하는건지?
- jwt로는 불가능함 (발급하는 순간 로그아웃을 컨트롤 할 수 없음 stateless 이기 때문, 체크를 안 하니까)
- 토큰을 세션처럼 사용하는 방식으로 해야함
- 백엔드만으로 구현하기 애매함
- db 하나만 사용하는 거 아님
- 엄밀히 다 분리 되는 게 맞음
- msa의 장점: 한 서비스가 다운 되어도 나머지는 돌아가게 하려고
- 하나만 사용한다? db 망가지면 모든 서비스 다운됨
- 분리하는 게 원칙적으로 맞다 → 비용이 비쌈
- 추가 질문
- db를 복제하는 등 서버마다 만들 때, 각 도메인 엔티티를 모두 분리해서 각 db에 넣는건지 db마다 모든 엔티티 넣는 게 맞는지
- 물리적으로 분리가 되는 게 맞고 모든 엔티티를 갖고 있을 수 없다.
- 동기화가 완전히 되는 건 불가능하다.
- 각 엔티티만 가고 있는게 맞다.
- 너무 힘들다? 하나만 써도 연습하는 수준에서는 괜찮음!
- db 분리했을 때 연관관계를 맺을 수 없다.
- 물리적으로 분리되
- MSA 질문
- 각 서비스마다 db를 분리 해야하는지, 연관관계는 어떻게 맺는지
- db 분리하는 게 맞다. 각 도메인만 저장해놓고
- 데이터가 물리적으로 분리되어있으니까 연관관계, join 불가능하다.
- api 통신을 통해서 마치 조인처럼 application에서 조립할 수 있음
- 속도 측면에서 일반적으로 느림
- 해결책: grpc (통신 프로토콜)
- 우리가 사용하는 http는 조금 무겁다. grpc 평균적으로 가벼움(빠르다)
- http2로 돌아가긴 함
- grpc 포폴 측면에서 의미있을거임(난이도 있음, 인터페이스에 미리 정해놓는 거라 귀찮음)
- { "orderNotifcation": ... } → orderNotifcation: 1 라고 가정해두고 1:…
- 미리 인터페이스에 저장해놓고 압축 같은 걸 해서 데이터 용량이 적으니 빨라짐
- 인터페이스 미리 지정 → protobuf라는 언어 사용 → 다른 서버에서 미리 알고 있어야하기 때문에 한 서버에서 수정하면 다른 서버에서도 수정해야함 → 귀찮다!
- 속도를 위해서라면 약간의 희생…
- ehcache 인메모리로 저장해놓는 거 정도는 괜찮음 (서버 간에 공유가 되지 않는다는 단점
- 잘 쓰면 좋다
- multi module로 구현한다면 공통 모듈을 정의해서 같이 사용하는 방식
- 라이브러리화해서 사용 가능 - gradle에 implement해서 사용
- 멀티 모듈화로 하는 걸 추천하심
- 공통 코드 관리, repository 따로 파는 거 귀찮음
- 빌드할 때 에러가 많이 남 → querydsl과 궁합이 좋지 않음
- 그치만 commit 공유되는 게 싫어서 나눠놓는 걸 선호하심
- 멀티 모듈 한 번 경험해보는 게 좋긴 함
- 추가 질문
- 멀티모듈 msa 에서 어느 서버에서 update되고 그것만 빌드해서 배포??
- ci/cd에서 잘 해주면 됨
- 한 모듈에서 update됐는지 어떻게 파악하는지?
- 브랜치별로 관리 - 하나의 브랜치로 하면 안됨
- 배포 브랜치를 기반으로 트리거해주면 됨
- 멀티모듈 msa 에서 어느 서버에서 update되고 그것만 빌드해서 배포??
- 안해도 된다고 생각하심
- 실제 서비스가 아니기 때문에 의미가 없다고 생각하심
- 포폴에서 그렇게 어필이 되는 요소는 아님
- 각 서비스마다 db를 분리 해야하는지, 연관관계는 어떻게 맺는지
- etc
- 멘토님은 join 많은 걸 선호하지 않으심
- refund안에 refund_detail 넣을 듯 (json 형태로)
- 변경될 내용이 아니기 때문에 이렇게 해도 괜찮다.
- 실무가 이론상 논리의 완벽함으로 이뤄지진 않는다…
- 모든걸 이론상 완벽하게 하지 않아도, 우리의 철학으로 해도 괜찮다… 인터넷에 나온 게 답은 아니다!
- 결제 시스템 - 각자 원하는대로
- toss payments 사용 https://www.tosspayments.com/
- 개인 프로젝트 패키지 구조
- controller, service, repository
- 각 패키지 안에서 도메인 별로 분리
- 개인 취향임
(4) 4월 22일 멘토링
- 스케줄러
- 굳이 특정 시간으로 하지 않아도 주문 후 상태, 특정 날짜가 범위 안에 있다면 상태 변경하도록 처리
- 하루에 한 번씩만 실행되도록
- 스케줄러 자체는 계속 돌고 있으면서 상태, 날짜에 대해 상태가 업데이트가 됨
- 개별 처리 → 조회 쿼리문을 한번에 날리고 filter를 잘 걸어라 (filter >> 1. 상태 2. 날짜)
- 상태 값에 대해 index 걸어주기
- 스프링 배치 사용해서 한번에 처리하는 방식도 있음
- 방법이 스케줄링 밖에 없을까요?
- 간단하게 기능 구현하려면 스프링 스케줄러 사용
- 지원해주는 라이브러리가 여러개 있으니 그 중에 골라서 사용
- 스케쥴러 모듈을 따로 나눠서
- 에러 발생하면 로그로 보여주거나 후처리 해주는 방식
- 에러난 거 빼고 나머지만 업데이트 해주는 등
- 테스트 코드
- 이슈가 나면 곤란한 기능만 테스트코드를 작성하셨다고 함
- 자코코: 커버리지 7~80% 정도로 맞춰서 작성
- 1차로 통합 테스트, 그 다음에는 테스트 필요한 것(레거시 코드, 또는 복잡한 함수)을 단위 테스트 수행
- mocking 아니면 샘플 데이터 사용
- 함수화해서 안 헷갈리게 잘 만들어러
- 주문하기 → 관련 엔티티 생성
- 환불하기 → 상태 변경
- 역할, 책임 나눠서 알아서 쏙쏙 뽑아올 수 있도록 구현하라
- 나만의 패턴
- dto 클래스 컨벤션
- 이름 정하는 시간도 줄이고, 인텔리제이 단축키 생성해서 활용
- 결론: 생산성을 높이세요,,,
항해99 취업 리부트 코스를 수강하고 작성한 콘텐츠 입니다.
댓글