Untitled

약 30분 ~ 1시간 정도 진행

  1. 기술 스택은 무엇을 썼나?
    1. Spring

      1. 왜 썼나? ( 게임 서버를 운영하는데 있어서는 Nest나 NPM 진영이 더 적합할텐데)
        1. (솔직한 답변), 팀원들의 이전 주차에서 스프링을 공부하기도 했고, 저희팀은 주제선정이 가장 늦게 된 팀이라 당장 서비스를 만드는게 중요했다. 그래서 노드를 새로 공부하는데 시간을 사용하는 것 보다는, 당장 코드를 짤 수 있는 스프링으로 빠르게 구현에 들어가는게 맞다고 판단했다.
        2. NestJS보다 러닝커브가 안높았다고 생각해서
      2. 다른 기술은 생각해봤나?
    2. NEXT

      1. 왜 썼나?
      2. 다른 기술은 생각해봤나?
    3. STOMP

      1. 왜 썼나?
        • 실시간 통신을 통해서 전달이 되어야하는 Core한 요소들은 캔버스에 그려져야하는 블록에 대한 정보들과 공격과, 아이템 사용현황등의 정보였습니다. 해당 요소들은 전부 텍스트로 서버와 클라이언트가 통신을 진행하였기 때문에 텍스트에 특화된 메시징 프로토콜을 제공하는 STOMP를 사용했다.
      2. 다른 기술은 생각해봤나?
        • 각 방에 대한 데이터와 사용자의 정보를 추가적으로 전달해야 했다. 일반 web socket의 경우, 빠르지만, 추가적인 메시지 헤더 없이 직접적으로 데이터를 주고받기 때문에, 별도의 처리가 필요했다. 하지만 STOMP의 경우 메시지 헤더가 이미 정의되어 있기 때문에 간단하게 추가정보를 전달할 수 있었다.
        • 또한, 메세지 브로커를 사용하여, 순서를 보장하는 기능도 비교적 편리하게 구현 가능하다는 장점도 있어서 STOMP를 사용하게 되었다.
        • 또한 여러 개의 독립적인 게임 실행을 위해, pub/sub 구조가 필요했다. 이를 구현하는데 용이한게 STOMP였기 때문에 사용했다. 물론 일반 web socket으로도 구현은 가능하나. STOMP에 이미 구현된 기능이 내장되어 있기 때문에, STOMP를 선택하게 되었다.
    4. Redis

      1. 왜 썼나?
        • 회원과 게임방에 상태를 Mapping하고 있는 정보를 서버에서 저장하고 있을 필요가 있었다. 하지만 RDB에 데이터를 넣기에는 유의미하지 않다고 판단하였고 비효율적이라고 생각했다. 그래서 서버 Application level에서 해당 정보를 가지고 있어야한다고 생각했다.
        • 그래서 초기에는 동시성이 보장되는 ConcurrentHashMap 을 사용하려고 했으나 서버의 상태에 영향을 안받는 인메모리 DB를 사용하고싶었고 마침 메시지 브로커도 필요하였기에 Redis를 사용했다.
      2. 다른 기술은 생각해봤나?
    5. Media Pipe

      1. 왜 썼나?
        • 속도가 빨라야 하며, 일반적인 브라우저에서 무리 없이 작동되어야 했다. 다행히도 미세한 트래킹이 필요 없었다. Mediapipe가 이에 적합했다. Mediapipe는 매우 빠른 속도로 손의 랜드마크를 x, y, z좌표로 추출해준다. 속도가 빠른 만큼 정확도가 떨어지긴 하지만 게임 조작에 사용되는 제스쳐의 구분이 명확했기에 이는 문제가 되지 않았다.
        • 또한, 웹 테트리스 게임이기에 mediapipe가 실행되는 환경이 항상 브라우저이다. 일반적인 경우 하드웨어 가속을 사용할 수 있어서 더욱 적합하였다.
      2. 다른 기술은 생각해봤나?
        • 더욱 미세한 손 움직임으로 게임을 조작해야할 경우 DeepHand를 사용하는 게 맞을 것 같다. DeepHand는 속도는 다소 느리지만 손의 미세한 움직임도 더 쉽게 잡아낼 수 있다. 왜냐하면 랜드마크 수를 지정해줄 수 있기 때문이다. Mediapipe는 커스터마이징이 제한적이다.
        • 하드웨어 가속이 불가능한 환경을 지원해야 한다면 OpenCV 오픈소스를 사용하는 게 맞을 것 같다. Mediapipe는 하드웨어 가속을 활용하기 때문이다.
        • 게임 조작에 사용되는 동작을 명확하게 구분했기 때문에 트래킹 성능이 뛰어난 모델인 DeepHand는 필요가 없었다.
    6. Discord

      1. 왜 썼나?
        1. 클라이언트와 서버간에 API를 연결할 때 서버에 전역 에러 핸들링처리가 되어있음에도 불구하고 예외가 발생했을 때 확인이 불가능한 이슈가 있었습니다.

          이를 해결하기 위해 Spring에서 제공하는 Logback과 Filter를 사용하여 Http 요청에 대한 정보들을 Parsing하고 에러가 나는 경우 이를 WebHook으로 Disocrd에 전송하여 에러 로그를 수집하는 기능을 만들었습니다.

          이를 통해서 개발 시 예외에 대해 확인하지 못하는 불편함을 해소할 수 있었습니다.

    7. 모니터링 - 그란파다나?

      1. 왜 썼나?
        • 프리티어에서 게임 서버를 운영하다보니 서버에 커넥션된 유저가 많아질 경우 서버가 쉽게 다운될것이라고 예상했습니다. 그렇기 때문에 현재 JVM이 Heap을 얼마나 사용하는지 유저수의 증가에 따라 서버가 얼마나 느려지고 GC가 처리되는 속도가 어느정도인지를 수집하고 시각화할 필요가 있었습니다. 그렇기에 사용했습니다.
      2. 다른 기술은 생각해봤나?
  2. 첫 번째 기술적 챌린지
  3. 두 번째 기술적 챌린지
    1. 구현할 때 다른 방법은 생각이 들지 않았는지?
      1. 클라이언트에서 3초동안 메세지를 보내지 않으면, 탈주로 간주하는 타임아웃 기반 로직도 생각을 해봤다.
      2. 그러나 저희 서비스는 대기방에 입장과 동시에 소켓연결을 하기 때문에, 대기방에서 레디 버튼을 3초마다 누르지 않으면 탈주로 간주되버린다. 그래서 그 방법은 적용할 수 없었다.
      3. 모든 클라이언트의 상태를 주기적으로 확인해야 하므로, 서버 부하가 증가하는 단점이 있다.
  4. 구현하면서 특별한 이슈는 없었나?
    1. 이성호 -

    2. 이강호

      1. 버퍼링
        1. 서버가 프리티어 EC2라 성능이 그리 좋지 않다. 그래서 게임을 진행하는 방이 2개 방 이상이 되면, 아주 가끔 버퍼링이 걸린다. 예를 들면 A방의 메세지를 처리하느라, B방의 메세지들을 스택에 쌓고, 보내지는 않는다. 그럼 ,B방의 유저는 상대 블록이 멈춘 것으로 보이는데, 시간이 조금 지나면, B방의 메세지를 처리하면서, 상대보드에 미뤄진 커맨드들이 빠르게 진행된다.
        2. EC2 성능을 올리고, 여러대의 서버와 로드밸런서를 가용하면 해결될 문제인 것 같다.
        3. 메세지 브로커에서 스케줄링을 하는 방법을 사용해도 해결될 것 같다.
          1. 메세지들을 endpoint에 있는 roomcode로 분류해서 map어 넣고
          2. 각 key를 순회하며 전송
    3. 윤호석 -

      1. 실시간성

        1. 실시간성으로만 봤을 때는 WebRTC가 더 유리할 수 있음. 하지만 테트리스 게임을 하다보면 필연적으로 서버에 전달해줄 데이터가 있기 때문에 STOMP가 더 적합하다.
      2. 메시지 브로커 (Spring Messaging vs Redis)

        1. Spring Messaging의 SimpMessageTemplate
          • 주로 WebSocket 기반의 실시간 애플리케이션에서 사용
          • STOMP 프로토콜 지원
          • 실시간 메시징을 위한 도구로, 실시간 게임, 채팅 등에 적합
          • WebSocket을 사용하여 연결 상태에 따라 메세지 전달 보장 (연결이 끊어지면 메세지 손실)
        2. Redis의 RedisTemplate
          • Redis 데이터베이스와의 상호작용을 위한 도구로, 데이터 검색, Pub/Sub 메시징 등을 지원
          • 여러 애플리케이션 인스턴스 간의 통신을 위해 사용
          • 실시간 메시징을 지원하나 구독자가 오프라인 상태면 메시지 받을 수 없음 또한 메시지 전달의 신뢰성 보장 X

        따라서 메시지 신뢰성을 보장하며 실시간성이 중요하고 WebSocket STOMP 기반의 우리 서비스에는 1번이 더 적합

    4. 김태훈 -

    5. 조승우 -

    6. 정종문 -

  5. 레이턴시는 어느정도 나오는지? 1.