-
Notifications
You must be signed in to change notification settings - Fork 0
채팅 진행상황 기록 및 정리
-
스터디룸 안의 채팅 / 피드백 채팅에서 둘다 필수적으로 들어가야 하는 값들이 있다.
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 결과 따위 필요가 없는거지...그냥 맞으면 실행 / 안맞으면 버림 이렇게 처리되어서..(?)
→
혹시 동건님 이거 관련해서 알고 계신점이 있다면 공유부탁드릴게요.....🤣
간단한 상황 테스트를 해보았다.
-
피드백 채팅 메세지를 보낼 때 꼭 필요한 값들을 누락한 채 채팅 보냄
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 병목 처리 혹은 이와 같은 상황에서의 대처 방법을 고민해 볼 필요가 있겠다..(사실 우리 서비스에서는 거의 없을 문제 같지만)