Skip to content

채팅 진행상황 기록 및 정리

yeen edited this page Feb 26, 2021 · 1 revision

1. 채팅 메세지 검증

  • 스터디룸 안의 채팅 / 피드백 채팅에서 둘다 필수적으로 들어가야 하는 값들이 있다.

    ex) chat : 스터디룸 id, 보낸 사람, 메세지

    ex) feedback: 스터디 히스토리 id, 받는 사람, 보낸 사람, 메세지

    위와 같은 값들이 들어오지 않을 경우 에러가 어마무시하게 발생하게 됨

  • @Valid 어노테이션 붙여서 채팅메세지 dto 검증 ! → @Payload 자체로는 검증이 불가함

     @MessageMapping("/chat.feedback")
     public void feedback(@Payload @Valid ChatDTO.FeedBackDTO feedback) throws JsonProcessingException {
     		chatProducer.sendFeedback(feedback);
     }

    @Valid 어노테이션 붙였을 경우 조건에 맞지않는 dto 보내졌을 때 아예 라우팅된 메소드 자체 실행이 안됨 (feedback 메소드 안에 안들어가는 느낌..?)

    → 이거 관련 자료가 읎따... 메세지 검증을 저렇게 해도 되는건지에 대한 의문이 들지만 일단 되긴된다...ㅎ 문서에 의하면 @Payload에도 자체 검증 로직이 포함되어 있는 거 같은데 실제로는 안된다..ㅎ

    여기서 의문점 @RequestMapping에서는 BindingResult 값으로 valid 결과 확인할 수 있었는데 @MessageMapping 에서는 이렇게 확인이 안됨..

    왜...?

    → 일단 뇌피셜..../chat.feedback 이라는 경로로 들어온 메세지 중 valid 결과에 맞는 메세지만 받아서 처리하겠다~ 이런거 아닐까... 아닌 메세지들은 그냥 버려지는거고..

    그리고 MessageMapping 이라는 단어를 직관적으로 해석해봐도 특정 메세지에 해당하는 것만 처리할 것 같은 느낌적인 느낌....그래서 valid 결과 따위 필요가 없는거지...그냥 맞으면 실행 / 안맞으면 버림 이렇게 처리되어서..(?)

    혹시 동건님 이거 관련해서 알고 계신점이 있다면 공유부탁드릴게요.....🤣

2. rabbitmq에서 메세지 받아온 후, 처리 하는 중에 db i/o 문제 혹은 다른 문제가 생겨 이 메세지 자체가 손실될 경우 ?

간단한 상황 테스트를 해보았다.

  • 피드백 채팅 메세지를 보낼 때 꼭 필요한 값들을 누락한 채 채팅 보냄
    ex)

    {
    // 스터디 히스토리 id 뺌
    "sendUserId" : 1,
    "receivedUserId" : 1,
    "message" : "hihi "
    }
  • consumer가 해당 메세지 받아서 처리할 때 스터디 내역 id 필요하지만 없는 상황 → db i/o 에 문제 생김

테스트 결과 :

  • 결론부터 말하면 메세지 처리 도중 db i/o 문제(혹은 다른문제)가 생길 때 해당 메세지는 손실되지 않는다!
  • consumer가 ack를 보내지 않음 → unacked로 처리됨
  • rabbitmq에서는 ack를 받거나 서버 연결이 끊어질 때까지 해당 메세지를 계속 보냄 (unacked 라서)

일단 테스트 전 나는 auto ack(디폴트)로 설정된 경우 rabbitmq에서 메세지를 받아오면 consumer가 rabbitmq에 ack 를 보냈을 거라 생각했다.

그래서 ack 를 수동적으로 보내면 해결가능할 것이라 생각 (db 트랜잭션이 끝난 후에 ack 발생시키도록)

그러나 @RabbitListener 에 자체적으로 트랜잭션 처리가 되어있는건지 (@Transactioanl 어노테이션이 없어도 동일하게 작동) db i/o 에 문제가 생기면 해당 메세지는 unacked 로 처리되었다. (즉 메세지를 받자마자 ack 를 보내는게 아님..똑똑해..)

unacked로 처리된 메세지는 지속적으로 consumer에게 다시 보내진다.

그리고 ack 를 받으면 삭제하고 서버가 중단되어 rabbitmq와 연결이 끊기면 unacked 메세지를 다시 해당 큐에 넣어서 처리되지 않은 메세지의 손실이 잃어나지 않게 한다.

📌 생각해 봐야 할 부분 :

unacked로 처리된 메세지는 지속적으로 consumer에게 다시 보내진다.

위와 같은 상황에서의 문제는 db에 병목현상이 일어나서 db에 데이터 삽입이 지연? 되고 있는 상황일 때

메세지를 계속적으로 보낸다면 만약 db가 다시 복구되었을 때 데이터 중복이 어마무시하게 되지 않을까...? (데이터 삽입 요청을 엄청 보내놨으니..)

db 병목 처리 혹은 이와 같은 상황에서의 대처 방법을 고민해 볼 필요가 있겠다..(사실 우리 서비스에서는 거의 없을 문제 같지만)