[항해99 취업리부트 WIL] 6주차

2024. 7. 2. 08:44·스케쥴/스터디

리팩토링 및 CI/CD 최적화

1. 개요

지난 2주 동안, 시스템 리팩토링과 CI/CD(Continuous Integration/Continuous Deployment) 최적화 작업에 중점을 두고 다양한 기술과 방법을 학습하고 적용하였습니다. 주요 학습 내용은 시스템 성능 향상, 코드 유지보수성 개선, 이벤트 기반 아키텍처 도입, 데이터 무결성 보장, 그리고 CI/CD 파이프라인 구축을 포함합니다.

2. 주요 리팩토링 작업

2.1 ReserveRequest 리팩토링

배경: 결제 생성 요청 로직이 Reservation 엔티티에 포함되어 있어 단일 책임 원칙(SRP)에 위배되었습니다.

변경 내용: 결제 생성 요청 로직을 Reservation에서 ReserveRequest로 이동하였습니다.

  • 기존: 결제 생성 로직이 Reservation 엔티티에 포함

      public Reservation toEntity(ConcertReader concertReader, UserReader userReader) {
          Concert concert = concertReader.findConcert(concertId);
          ConcertDate concertDate = concertReader.findConcertDate(concertDateId);
          Seat seat = concertReader.findSeat(seatId);
          User user = userReader.findUser(userId);
    
          return Reservation.builder()
                  .concert(concert)
                  .concertDate(concertDate)
                  .seat(seat)
                  .user(user)
                  .status(Reservation.Status.ING)
                  .build();
      }
  • 변경 후: 결제 생성 로직을 ReserveRequest로 분리

      public Reservation toEntity() {
          return Reservation.builder()
                  .concertId(concertId)
                  .concertDateId(concertDateId)
                  .seatId(seatId)
                  .userId(userId)
                  .status(Reservation.Status.ING)
                  .build();
      }
    
      public CreatePaymentReqDto toCreatePayment(Reservation reservation) {
          return new CreatePaymentReqDto(reservation, Payment.Status.READY, reservation.getSeat().getPrice());
      }

결과:

  • 단일 책임 원칙을 준수하여 각 클래스가 자신의 역할에 집중할 수 있게 되었습니다.
  • 코드의 유지보수성과 가독성이 향상되었습니다.

2.2 ReservationEventListener 추가

배경: 예약 점유 이벤트를 처리하기 위한 비동기 이벤트 리스너가 필요하였습니다.

변경 내용: 예약 점유 이벤트를 처리하기 위해 이벤트 리스너를 추가하였습니다.

  • 신규 추가:

      @Component
      @RequiredArgsConstructor
      public class ReservationEventListener {
          private final ReservationMonitor reservationMonitor;
    
          @EventListener
          @Transactional(propagation = Propagation.REQUIRES_NEW)
          public void onReservationOccupiedEvent(ReservationOccupiedEvent event) {
              reservationMonitor.occupyReservation(event.getReservationId());
          }
      }

결과:

  • 이벤트 기반 아키텍처를 통해 비동기적으로 예약 점유 상태를 관리할 수 있게 되었습니다.
  • 시스템의 모듈성과 확장성이 높아졌습니다.
  • @Transactional(propagation = Propagation.REQUIRES_NEW)를 사용하여 새로운 트랜잭션에서 이벤트를 처리함으로써, 기존 트랜잭션과의 충돌을 방지하였습니다.

2.3 ReservationOccupiedEvent 추가

배경: 예약 점유 이벤트를 정의하여 이벤트 기반 아키텍처를 지원할 필요가 있었습니다.

변경 내용: 예약 점유 이벤트를 정의하였습니다.

  • 신규 추가:

      @Getter
      public class ReservationOccupiedEvent extends ApplicationEvent {
          private final Long reservationId;
    
          public ReservationOccupiedEvent(Object source, Long reservationId) {
              super(source);
              this.reservationId = reservationId;
          }
      }

결과:

  • 시스템의 모듈성과 확장성이 높아졌습니다.
  • 이벤트 기반 아키텍처를 통해 비동기적으로 예약 점유 상태를 관리할 수 있게 되었습니다.

2.4 WaitingQueue 상태 관리 추가

배경: 대기열의 상태를 명확히 관리할 필요가 있었습니다.

변경 내용: WaitingQueue 클래스에 상태를 관리하는 status 필드를 추가하였습니다.

  • 기존: 상태 관리 필드가 없음
  • 변경 후:
      @Column(nullable = false)
      @Enumerated(EnumType.STRING)
      private Status status;

결과:

  • 대기열 상태 관리가 명확해져 시스템의 안정성과 데이터 일관성이 향상되었습니다.

2.5 ReservationService 예외 처리 변경

배경: 예약 중복 시 발생하는 예외를 더 적합한 예외로 변경할 필요가 있었습니다.

변경 내용: ObjectOptimisticLockingFailureException에서 DataIntegrityViolationException으로 예외를 변경하였습니다.

  • 기존:
      } catch (ObjectOptimisticLockingFailureException e) {
          // 버전 충돌 -> "이미 선택된 좌석입니다." 반환
  • 변경 후:
      } catch (DataIntegrityViolationException e) {
          // 유니크 제약 조건(concertDateId, seatId) 위반 시
          throw new CustomException(ReservationExceptionEnum.ALREADY_RESERVED, null, LogLevel.INFO);

결과:

  • 더 적절한 예외 처리를 통해 중복 예약 시도를 효과적으로 관리할 수 있게 되었습니다.

3. CI/CD 파이프라인 구축

3.1 GitHub Actions 설정

배경: 효율적인 CI/CD 파이프라인을 구축하여 코드 변경이 자동으로 빌드, 테스트, 배포되도록 설정할 필요가 있었습니다.

변경 내용: GitHub Actions를 사용하여 CI/CD 파이프라인을 설정하였습니다.

3.2 CI/CD 파이프라인 세부 구현

CI develop Pipeline:

  • 개발자가 develop 또는 release-* 브랜치에 푸시하거나 PR을 생성하면, GitHub Actions가 CI develop Pipeline을 시작합니다.
  • 주요 단계:
    • Redis, Zookeeper, Kafka 서비스 시작
    • 코드 체크아웃 및 JDK 설정
    • 테스트 실행 및 리포트 생성
    • Checkstyle 실행
    • 프로젝트 빌드
name: CI develop Pipeline

on:
  push:
    branches:
      - develop
      - release-*
  pull_request:
    branches:
      - develop
      - release-*

jobs:
  build:
    runs-on: ubuntu-latest

    services:
      redis:
        image: redis
        ports:
          - 6379:6379
      zookeeper:
        image: wurstmeister/zookeeper
        ports:
          - 2181:2181
      kafka:
        image: wurstmeister/kafka
        ports:
          - 9092:9092

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up JDK 11
        uses: actions/setup-java@v2
        with:
          java-version: '11'

      - name: Build with Gradle
        run: ./gradlew build

      - name: Run tests
        run: ./gradlew test

      - name: Generate report
        run: ./gradlew jacocoTestReport

      - name: Run Checkstyle
        run: ./gradlew checkstyleMain

Dev CD Pipeline:

  • 개발자가 release-* 브랜치에 푸시하면 GitHub Actions가 Dev CD Pipeline을 시작합니다.
  • 주요 단계:
    • AWS 자격 증명 설정
    • Docker 이미지 빌드 및 ECR에 푸시
name: Dev CD Pipeline

on:
  push:
    branches:
      - release-*

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to Amazon ECR
        run: |
          aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com

      - name: Build and push Docker image
        run: |
          docker build -t ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/my-app:${{ github.sha }} .
          docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/my-app:${{ github.sha }}

      - name: Deploy to ECS
        run: |
          aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment

Prod CD Pipeline:

  • **개발자가 master 브랜치에 푸시하면 GitHub Actions가 Prod CD Pipeline을 시작합니다

.**

  • 주요 단계:
    • AWS 자격 증명 설정
    • Docker 이미지 빌드 및 ECR에 푸시
    • ECS 태스크 정의 배포
name: Prod CD Pipeline

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to Amazon ECR
        run: |
          aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com

      - name: Build and push Docker image
        run: |
          docker build -t ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/my-app:${{ github.sha }} .
          docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/my-app:${{ github.sha }}

      - name: Deploy to ECS
        run: |
          aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment

4. CI/CD 파이프라인의 이점

4.1 자동화된 테스트 및 배포

  • 이점: 코드 변경이 자동으로 빌드, 테스트, 배포되므로 개발 주기가 단축되고, 인적 오류가 줄어듭니다.

4.2 일관된 배포

  • 이점: 동일한 환경에서 동일한 절차로 배포가 이루어져 환경 간 일관성이 보장됩니다.

4.3 빠른 피드백 루프

  • 이점: 코드 변경 시 즉각적인 피드백을 받을 수 있어 문제를 빠르게 식별하고 해결할 수 있습니다.

4.4 향상된 협업

  • 이점: 팀원 간의 코드 변경 사항이 자동으로 통합되고 테스트되므로 협업이 원활해집니다.

5. 결론

지난 2주 동안의 학습과 실습을 통해 시스템 리팩토링과 CI/CD 최적화 작업을 성공적으로 수행할 수 있었습니다. 이를 통해 시스템의 성능과 유지보수성이 크게 향상되었으며, 자동화된 CI/CD 파이프라인을 통해 개발 효율성과 신뢰성을 높일 수 있었습니다. 이러한 개선 작업은 시스템의 장기적인 안정성과 확장성에 기여할 것입니다.

저작자표시 (새창열림)

'스케쥴 > 스터디' 카테고리의 다른 글

[항해99 취업리부트 WIL] 8주차  (0) 2024.07.16
[항해99 취업리부트 WIL] 7주차  (0) 2024.07.09
[항해99 취업리부트 WIL] 5주차  (0) 2024.06.24
[항해99 취업리부트 TIL] 4주차 4일  (1) 2024.06.17
[항해99 취업리부트 TIL] 4주차 3일  (0) 2024.06.15
'스케쥴/스터디' 카테고리의 다른 글
  • [항해99 취업리부트 WIL] 8주차
  • [항해99 취업리부트 WIL] 7주차
  • [항해99 취업리부트 WIL] 5주차
  • [항해99 취업리부트 TIL] 4주차 4일
hyeseong-dev
hyeseong-dev
안녕하세요. 백엔드 개발자 이혜성입니다.
  • hyeseong-dev
    어제 오늘 그리고 내일
    hyeseong-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (283)
      • 여러가지 (107)
        • 알고리즘 & 자료구조 (72)
        • 오류 (4)
        • 이것저것 (29)
        • 일기 (1)
      • 프레임워크 (39)
        • 자바 스프링 (39)
        • React Native (0)
      • 프로그래밍 언어 (38)
        • 파이썬 (30)
        • 자바 (3)
        • 스프링부트 (5)
      • 운영체제 (0)
      • DB (17)
        • SQL (0)
        • Redis (17)
      • 클라우드 컴퓨팅 (2)
        • 도커 (2)
        • AWS (0)
      • 스케쥴 (65)
        • 세미나 (0)
        • 수료 (0)
        • 스터디 (24)
        • 시험 (41)
      • 트러블슈팅 (1)
      • 자격증 (0)
        • 정보처리기사 (0)
      • 재태크 (5)
        • 암호화폐 (5)
        • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    취업리부트
    프로그래머스
    Redis
    reactor
    docker
    OOP
    그리디
    AWS
    Spring WebFlux
    Spring Boot
    celery
    mybatis
    WebFlux
    시험
    SAA
    파이썬
    RDS
    spring
    Python
    ecs
    자바
    java
    #개발자포트폴리오 #개발자이력서 #개발자취업 #개발자취준 #코딩테스트 #항해99 #취리코 #취업리부트코스
    EC2
    DP
    항해99
    FastAPI
    백준
    완전탐색
    Docker-compose
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hyeseong-dev
[항해99 취업리부트 WIL] 6주차
상단으로

티스토리툴바