몽고디비로 web socket 예제를 구현한 것을 보았다
디스크 기반 nosql은 처음 사용해본다.
몽고디비가 어떻게 데이터를 빨리 찾는지를 공부해보고자 했다.
그런데 보면 볼수록 몽고디비라고 그렇게 특별한 기능이 있는건 아니였다.
예를들어, redis는 일반적으로 key를 토대로 데이터를 O(1)만에 찾을 수 있다.
하지만 몽고디비는 RDB와 동일하게 인덱스를 생성하고, 그 인덱스를 통해서 데이터를 빠르게 찾아오는 것 이었다.
이거는 약간 충격이었다.
그리고 내가 nosql에 대해서 가지고 있던 지식도 약간의 오해가 있다는 것도 알았다.
nosql 이라고 무조건 빠른게 아니라 not only sql이고, 일반적인 테이블에 데이터를 저장하는게 아니라
다양한 형태(key:value, document(json)) 형태로 데이터를 저장할 때, 사용하는 것이 nosql 이었다.
그런데 여기서 의문점이 들었다.
채팅 데이터는 일반적인 다른 데이터에 비해 엄청 많은 양이 생성된다고 생각한다.
또한, 채팅 데이터는 text 형태이기 때문에 rdb보다 유연한 구조를 저장하는 nosql을 사용하는게 적절하다.
그런데 이런 많은 데이터를 빨리 fetch 해오는게 관점일텐데 mongodb라는 nosql을 볼때에는 인덱스 말고는 빠른 데이터 조회가 가능해보이지는 않는다.
어떻게 채팅 데이터를 빠르게 가져오는 것일까? 단순히 인덱스(생성일자)를 통해서 가져오는 것인가?
그리고 rdb의 비정규화를 통해서 mongodb랑 똑같은 동작을 할 수 있을거 같은데 굳이 mongodb를 사용하는 이유는?
단지 유연한 자료 특성 때문에?
mongodb의 기본 철학 -> 읽기 속도와 독립성 우선
몽고디비는 데이터 중복이 기본적으로 ㅇ -> 메시지의 경우 어떤 sender가 보냈는지
만약 의도적으로 sender name중 하나를 바꾼다면? -> 그냥 그게 보인다. (우리가 이걸 모두 처리하고 싶다면 update 쿼리를 날려야함)
mongodb로 테스트해보기


이렇게 잘 보인다

홍길동을 바꾼다면?

1. 영희에게 보이는 이름은 다른이름

2. 길동이도 본인 메시지가 아닌것처럼 보이게 된다.

web-socket 실습하기
web socket 실습 예제가 있었지만 처음부터 하나하나 구현하는게 더 머리에 남을거 같아서 쌩 기초부터 시작했다.
특히나 인증(시큐리티)없이 구현하는게 더 빠르게 ws를 이해할 수 있다고 생각해서 처음부터 시작한거도 있다.
에러사항
1. Uncaught ReferenceError: global is not defined
이 에러는 vue 3하고 STOMPJS를 사용할 때, 브라우저에 없는 Node.js 변수를 참조하려고 해서 생기는 문제이다.
vite.config.js에서
define: {
global: 'globalThis' // 핵심: global을 globalThis로 대체
},
define을 위와 같이 바꿔주면 된다.
2. 로그인 처리
나는 분명 시큐리티 코드를 추가하지 않았는데 ws 연결시에 alert 창으로 자꾸 로그인을 하라고 창이 떴다.
이게 무슨일이지? 하고 1시간동안 찾다가 build.gradle에 security 라이브러리가 들어가있는걸 확인했다....
분명 처음부터 시작했는데, 팀 레포로 옮기는 과정에서 commit한게 섞여서 문제가 생긴거같다.
build.gradle에서 security 관련된 설정을 제거한 후에 gradle을 새로고침하니 문제 없어짐!!!
3. 스프링 lombok 문제
ws 연결과 메시지 전송은 잘 됐다.
그런데 자꾸 백엔드에서 null 값을 받아왔다.
json으로 직렬화 한 후에 백엔드에서 역직렬화를 통해서 java 객체로 매핑한다.
이때, 기본적으로 ObjectMapper가 사용되고 MappingJackson2MessageConverter가 사용된다고 알고있다.
그런데, 문제가 계속해서 발생해서 configureMessageConverters로 수동 등록을 해줬는데도 문제가 생겼다.
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
// Jackson 컨버터 수동 등록
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(new ObjectMapper());
converter.setPrettyPrint(true);
System.out.println("=== 메시지 컨버터 등록됨 ===");
messageConverters.add(converter);
return false; // true로 하면 기본 컨버터 무시하므로 false 유지
}
그런데도 안됐다.
문제는 lombok 설정이 안되어있던것...
따라서 Jackson 객체가 생성자가 없으니 생성x, setter가 없으니 값을 넣어주지 못하니 null이 들어갔던 것이다.

새로운 프로젝트를 할때에는 롬복 설정부터 해주자.

모든 사람이 다 잘 받고있다!!!
해야할것
1. security를 추가해서 사용자 정보(이름) 다르게 보이게 하기
2. db 연결(rdb, nosql == mongodb)해서 데이터 저장 + 채팅창 내역이 뜨게하기
-> 특히나 적용할 프로젝트는 다대다이기 때문에 이거 어떻게 할지 db 스키마 설계부터 진행하기(dto도 뭘로 받아올껀지)
3. 지금은 하나의 uri (/app/chat)으로 하는데 채팅방마다 다른 채팅방으로 연결되게하기
4. 지금은 simple broker를 쓰는데 이것도 결국 스프링에서 제공하는거니까 사용자가 엄청 많아지면 문제가 생김
-> rabbitMQ로 어떻게 이벤트를 분산하는지 생각하기
'일기' 카테고리의 다른 글
| 6.9 - 오늘의 기록 (채팅 이해, 다양한 방법으로 구현) (0) | 2025.06.09 |
|---|---|
| 5.26 - 오늘의 기록 (채팅에 어떤 db를 사용하는게 맞을까?) (0) | 2025.05.26 |
| 5.23 오늘의 기록 (2) | 2025.05.23 |
| 5.21 - 오늘의 일기 (채팅 고도화) (0) | 2025.05.21 |
| 5.19 - 오늘의 일기 (web socket) (1) | 2025.05.20 |