1. 이번주 트러블 슈팅 :

  • 시그널링 서버 연결 시에 sendMessage() 메소드가 동시적으로 작동했을 때 소켓 연결이 끊어지는 이슈가 있었는데, 이를 synchronized 를 활용해서 순차적으로 진행될 수 있도록 변경.
  • 서비스 로직 정상 작동 확인 후 해당 서비스 로직에 다른 서비스 로직을 끼워넣었을 때, 끼워 넣은 서비스 로직이 실행되는 않는 이슈 발생 → 끼워넣은 서비스 로직에서 데이터를 삭제하는 로직이 포함되어 있어서 첫 서비스 로직에서 @Transactional 을 붙여준 뒤 해결
  • 리프레쉬 토큰 사용을 위한 Redis 데이터 베이스에서 TTL을 걸어두었지만 시간이 지나도 DB에서 삭제되지 않는 것으로 확인 → Redis에서 만료 시간을 설정하는 방법은 RedisTemplate 오퍼레이션 사용시 만료 시간을 설정하는 법과 CrudRepository를 이용하여 저장할 객체에 timeToLive를 설정하는 방법 두 가지가 있는데, RedisTemplate만을 이용하면서 객체에 timeToLive를 적용해 제대로 적용되지 않음. 제대로 적용할 수 있게 CrudRepository를 사용해 timeToLive가 적용될 수 있도록 해결
  • 게시판 이미지 S3에 업로드 후 저장 경로가 서비스 도메인과 동일하게 시작 → SSL 인증이 안 되기 때문에 프론트에서 이미지를 보여줄 수 없음 → S3 버킷 이름을 변경하여 해결
  • 뒤로가기 버튼이 아닌 인터넷 브라우저 탭 강제 종료 시 데이터가 변하지 않는 상황 발생 → WebRTC 연결 끊기는 로직에 게임 강제 종료 로직 추가

2. 프로젝트에 새롭게 도입한 기술 : 

  • CI/CD 자동화 배포
    • github action을 통해 CI를 거친 빌드 파일이 S3에 저장된 다음 AWS CodeDeploy에 의해 EC2에 배포됩니다.
    • 도입 이유 : 자동 테스트, 빌드, 배포를 통해 개발자가 더 편리하게 개발에만 집중 할 수 있도록 해줍니다.
  • 동시성 제어
    • 비관적 락을 통한 DB제어와 synchronized를 활용한 session 동시성 제어 적용
    • DB 제어 도입 이유: 한방에 동시 입장시 동일한 데이터에 대한 수정 요청이 발생해 데이터 일관성에 문제가 생길 것이라 생각해 이를 방지하기 위해 락을 설정했습니다.
    • 세션 제어 도입 이유: 시그널링 서버에 여러 명이 동시에 접속 시 Websocketsession 충돌로 연결이 끊기는 이슈를 해결하기 위해 도입했습니다. session에서 sendMessage는 동시 전송이 불가능하여 이를 차례대로 처리할 수 있도록 해당 메소드에 synchronized를 적용했습니다.

 

3. 이번주 한 일 :

  • CI/CD (Github Actions, AWS CodeDeploy)
  • 방 입장하기 동시성 제어
  • 와일드 카드 또는 제네릭 형태의 return 값 구체화
  • 커뮤니티 게시판 API
  • 시그널링 서버 메세지 발송 메소드 동시성 제어
  • S3 이미지 업로드 기능 구현
  • Refresh 토큰 구현 중 (FE와 맞춰봐야 함)
  • GameStartSet DB Redis에서 MySQL로 변경
  • DB 관련 로직 RepositoryService로 분류하여 리팩토링
  • HashMap 타입 일괄 Map으로 수정 (추후 유지보수를 위해 상위 클래스인 Map으로 수정)
  • GameService와 GameRearService 관심사에 맞게 통합 운영 (리팩토링)
  • 게임 키워드 추가
  • 추후 마케팅 작업을 위한 유저 별 방 생성 횟수, 플레이타임 등 Column값 추가 및 로직 구현

 

4. 궁금했던 부분 

  • 현재 synchronized 로 동시성을 제어하는 것이 굉장히 느리다고 알고 있는데, Spring 공식 문서에서 메세지 전송을 동기화 하기 위해서 ConcurrentWebSocketSessionDecorator 도 제공하고 있다고 해서 두 가지 중에 고민입니다. 
    • 일단 웹소켓을 못가져오는 이유를 먼저 찾아보고 그래도 모르겠으면
    • 일단 Concurr ~ 먼저 적용 , 그래도 안되면 Synchronized 사용 .
    • 최대한 싱크로나이즈드는 지양하는게 좋다. 성능이 너무 안좋음.
  • Controller 단에서 ResponseEntity<?>와 같이 반환 데이터 타입을 명시적으로 정해주지 않고 사용했었는데, Front로 내보내는 반환 값으로 와일드카드를 쓴다는 건 반환하는 메소드에서 의도한 타입으로 나가든, 의도하지 않은 타입으로 나가든 성공적으로 나가게 되는거 같습니다. 내보내는 반환 값을 명확하게 설정해주면 잘못된 타입으로 나가는 걸 방지해줄 수 있기 때문에 명시적으로 사용하는 거 같은데 옳게 이해한 걸까요? -
    • 옵션 1. 하이브리드 방식
    • ? extends Object - 이런식으로 쓸 수 있다. 특정 클래스의 하위클래스만 내보내는 방법이기도 하다
    • 옵션 2. ? 그대로 사용 - 문제는 없음.
  • 현재 메세지 브로커를 STOMP 내장 브로커를 활용하고 있는데, 스케일아웃을 했을 때 동작하지 않는 것으로 알고있습니다. 만약의 상황에서 서버를 스케일아웃을 했을 때 정상작동하도록 메세지 브로커로 Redis나 RabbitMQ를 사용하는 것이 나을까요?
    • 현재 메시지브로커 역할을 하는지? 멘토님이 알기론 아님.
    • 브로커 입장에서는 이미 바라보고 있는 데이터가 스케일 아웃을 하던 안하던 상관없다.
    • 인스턴스 객체가 인메모리상에 뜨는데 얘가 다른 인스턴스의 스톰프를 알아야되는 상황이 맞는지 ?
    • 그게 아니라면 굳이 외부메시지브로커를 사용할 필요가 없다.

 

5. 다음주 할 일 : 서비스 배포 !!

+ Recent posts