edu-pi / Backend-Lms-Server

0 stars 0 forks source link

[Feat] 학생 진척도 기능 구현 - 완료, 도움 버튼 #9

Closed SongGwanSeok closed 1 week ago

SongGwanSeok commented 2 weeks ago

📝 Description

무엇을?

왜?

❗️Todo

ETC

기타사항

SongGwanSeok commented 2 weeks ago

이 기능에 적절한 기술 고민

  1. Short Polling : 짧은 시간을 설정해 주기적으로 server에 변경사항이 있는지 확인하는 요청을 보낸다.
  2. Long Polling : 긴 시간을 설정해 주기적으로 server에 변경사항이 있는지 확인하는 요청을 보낸다.
  3. WebSocket : 서버와 클라이언트의 양방향 통신이 가능하다.
  4. SSE(Server-Sent Events) : 클라이언트가 서버로부터 지속적으로 업데이트를 받는다.
  5. Redis Pub/Sub : Redis를 이용해서
  6. 메시지 브로커(Kafka, RebbitMQ) : 이벤트를 발행하고 이를 구독하여 처리할 수 있다.

SSE가 가장 적당할듯? 양방향 통신이 필요하지않고 너무 무겁게 구성하고싶지 않기 때문

SSE란?

사용자 요청이 없어도 이벤트가 있을 때 정보를 받을 수 있는 기술

Spring에서 Server-Sent-Events 구현하기 SSE 예제 코드

HTTP1.1의 경우는 하나의 브라우저에 최대 6개의 SSE 연결을 할 수 있고, HTTP2의 경우에는 최대 100개까지 가능하다.

SongGwanSeok commented 2 weeks ago

SSE(Server Sent Event) 기술을 사용할 때 요청이 끝났는지 어떻게 확인하지?

내가 이해한 SSE 기술

  1. 교육자가 학생 진척도 페이지에 들어가면 get요청으로 sse connection(teacherId포함)을 맺는다.
  2. 학생이 버튼을 클릭하면 학생이 포함된 classroom을 조회해 teacherId를 가져와 해당하는 유저에게 sse event(studentId, 어떤 요청인지)를 보낸다.
  3. 교육자는 서버에게서 오는 이벤트를 듣고 있다가 이벤트가 오면 해당하는 studentId의 값을 적절하게 수정한다.

그렇다면 여기서 생기는 의문점

  1. 학생의 상태는 어떻게 관리할 것인가?
    • db에 학생의 상태 저장?
    • 상태를 저장하지 않으면 새로고침하면 다 날아가나?
  2. 교육자가 그냥 탭을 닫으면 connection은 어떻게 되나?
    • 탭을 닫으면서 connection이 끊기나? -> 서버가 인식하고 onCompletion()을 실행시킴
    • 요청이 일정시간 없으면 서버에 저장한 Connection이 끊기나? -> timeout 시간동안 아무 요청이 없으면 onTimeout()을 실행시킴
    • timeout 시간을 설정해놓으면 알아서 connection이 끊기는 건가? -> timeout 시간동안 아무 데이터를 보내지 않으면 timeout
  3. connection없이 학생이 요청만 보내면 어떻게 되나?
    • 쌓이고 있다가 교육자가 접속하면 그대로 받아지나?
    • 받은 요청을 확인했다는 표시가 있나?
  4. 다중 서버인 경우에 Map에 저장하지 못하는데 Redis를 사용해야 하나?
    • MQ 사용 -> 비싸다... redis가 가장 어울리긴 하는데
      1. Redis pub/sub
        • 사용자가 주시하고 있지 않다면 메시지는 사라진다.
        • 다른 MQ와 다르게 수신을 확인하지 않아 전송이 보장되지 않는다.
      2. kafka
        • publisher가 topic을 통해 데이터를 전송한다.
        • subscriber는 원하는 topic을 구독해 메시지를 읽어온다.
        • 클러스터 내, broker에 대한 분산처리는 ZooKeeper가 담당한다.
      3. RabbitMQ
        • queue에 들어가기 전, exchange라는 단계를 추가로 거친다.
        • 데이터 처리보단, 관리적 측면이나 다양한 기능 구현을 위한 서비스를 구축할 때 사용한다.
    • Eureka를 사용해서 sseEmitter 전파? -> 이것도 서버를 하나 더 띄워야 한다.
      • 같은 서비스의 다른 인스턴스 들에 sseEmitter를 전송해 동기화해주는 방식은 어떨까
    • RDB를 이용한 방식
      • host가 그 페이지에 들어오면 클래스룸 guest들의 상태를 모두 0으로 초기화하고 connection 연결, guest들이 요청을 보내면 그룹의 Host에게 요청 전달