์ด์ ์ STOMP๋ฅผ ์ฌ์ฉํด์ ์ฑํ ์๋น์ค๋ฅผ ๊ตฌํํด ๋ณด์๋ค. ์ด๋ฒ์๋ ๋น๋๊ธฐ ์๋ฒ์ธ Netty ์๋ฒ์ MongoDB๋ก ๊ตฌํํ ์ฑํ ์๋น์ค๋ฅผ ๊ตฌํํด๋ณด์๋ค.
๊ทธ ์ ์ mySQL๊ณผ MongoDB์ ์ฐจ์ด์ ์ ์ง๊ณ ๋์ด๊ฐ์
mySQL์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ (RDBMS)์ด๋ค.
- ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ก์ธ์ค๋ฅผ ์ํด ๊ตฌ์กฐํ๋ ์ฟผ๋ฆฌ ์ธ์ด(SQL)๋ฅผ ์ฌ์ฉํ๋ค.
- ์ฌ๋ฌ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ํ์ํ ๋ Join์ ์ฌ์ฉํ์ฌ ์ก์ธ์คํ๋ค.
MongoDB๋ ๋ฐ์ดํฐ๋ฅผ JSON๊ณผ ์ ์ฌํ ๋ฌธ์๋กค ์ ์ฅํ๋ NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์ด๋ค.
- ๋ฌธ์๋ ๊ด๋ จ ์ ๋ณด๋ฅผ ํจ๊ป ์ ์ฅํ๊ณ ์ก์ธ์ค๋ฅผ ์ํด MongoDB ์ฟผ๋ฆฌ ์ธ์ด(MQL)์ ์ฌ์ฉ
- ํ๋๋ ๋ฌธ์๋ง๋ค ๋ค๋ฅผ ์ ์์
- ๋ฌธ์ ๊ตฌ์กฐ๋ฅผ ์ ์ธํ ํ์๊ฐ ์์
SQL์ ์ธ์ ์ฌ์ฉํ๋๊ฒ ์ข์๊น?
- ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋ ๋ฐ์ดํฐ๊ฐ ์์ฃผ ๋ณ๊ฒฝ(์์ )๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ผ ๊ฒฝ์ฐ (NoSQL์์๋ผ๋ฉด ์ฌ๋ฌ ์ปฌ๋ ์ ์ ๋ชจ๋ ์์ ํด์ค์ผ๋ง ํจ.)
- ๋ณ๊ฒฝ๋ ์ฌ์ง๊ฐ ์๊ณ , ๋ช ํํ ์คํค๋ง๊ฐ ์ฌ์ฉ์์ ๋ฐ์ดํฐ์๊ฒ ์ค์ํ ๊ฒฝ์ฐ
NoSQL์ ์ธ์ ์ฌ์ฉํ๋๊ฒ ์ข์๊น?
- ์ ํํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ ์๊ฑฐ๋ ๋ณ๊ฒฝ / ํ์ฅ ๋ ์ ์๋ ๊ฒฝ์ฐ
- ์ฝ๊ธฐ(read)์ฒ๋ฆฌ๋ฅผ ์์ฃผํ์ง๋ง, ๋ฐ์ดํฐ๋ฅผ ์์ฃผ ๋ณ๊ฒฝ(update)ํ์ง ์๋ ๊ฒฝ์ฐ (์ฆ, ํ๋ฒ์ ๋ณ๊ฒฝ์ผ๋ก ์์ญ ๊ฐ์ ๋ฌธ์๋ฅผ ์ ๋ฐ์ดํธ ํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ํ์ผ๋ก ํ์ฅํด์ผ ํ๋ ๊ฒฝ์ฐ ( ์ฆ, ๋ง๋ํ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ค์ผ ํ๋ ๊ฒฝ์ฐ)
๋ฐ๋ผ์ ์ด ํ๋ก์ ํธ์์ ๋๋์ ์ฑํ ์ ์กฐํํ ๋ ์ฑ๋ฅ์ ๋ด๊ธฐ ์ํด MongoDB๋ฅผ ์ฌ์ฉํ์๋ค.
Netty ์๋ฒ๋ฅผ ์ ํํ ์ด์
์ค๋ ๋ ๊ธฐ๋ฐ ์๋ฒ(ํฐ์ผ)์ ์์ฒญ๋ง๋ค ์ค๋ ๋๊ฐ ์์ฑ๋๋ค. ์คํ๋ง 4.0 ๊น์ง๋ ์๋ธ๋ฆฟ ๊ธฐ๋ฐ์ด๋ค.
A ์ฌ์ฉ์๊ฐ ์๋ฒ์ ์์ฒญ์ํ๊ณ ์๋ฒ๊ฐ DB๋ฅผ ์กฐํํ๋ค๊ณ ๊ฐ์ ํด๋ณด์. ์ด๋, ์๋ก์ด B ์ฌ์ฉ์๊ฐ ๋์์ ์์ฒญ์ ํ ์ ์์ด์ผํ๋ฏ๋ก ์๋ก์ด ์ค๋ ๋๋ฅผ ๋ง๋ค์ด์ ์์ฒญ์ ๋ณด๋ธ๋ค. ๋ง์ฝ ์ ์ ๊ฐ ๋์ด๋๋ค๊ณ ํ๋ฉด ์ค๋ ๋์ ๊ฐ์๊ฐ ๊ณ์ํด์ ๋์ด๋๊ณ , ์๋ฒ์ ํฐ ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๊ฒ ๋๋ค.
์๋ฒ์ ํฐ ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๋ ์ด์ ๋ context-switching ๋๋ฌธ์ด๋ค.
์คํ๋ง 5.0์ ๊ธฐ๋ณธ์ ์ผ๋ก Netty ์๋ฒ๋ฅผ ์ฌ์ฉํ๋ค. ๋น๋๊ธฐ ์๋ฒ์ ๊ฐ์ฅ ํฐ ํน์ง ์ค ํ๋๋ ์ค๋ ๋๊ฐ ํ๋์ธ ๊ฒ์ด๋ค.
A์ฌ์ฉ์๊ฐ ์๋ฒ์ ์์ฒญ์ํ๊ณ ์๋ฒ๊ฐ DB๋ฅผ ์กฐํํ๊ณ ์๋ต๋ฐ๋๋ฐ 3์ด๊ฐ ๊ฑธ๋ฆฐ๋ค๊ณ ๊ฐ์ ํด๋ณด์. ๊ทธ ์ฌ์ด์ ์๋ก์ด B ์ฌ์ฉ์๊ฐ ์๋ฒ์ ์์ฒญ์ ๋ณด๋ธ๋ค๋ฉด A์ DB ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋๋์ B ์ฌ์ฉ์์ ์์ฒญ์ ์ฒ๋ฆฌํด์ค๋ค. ๊ทธ๋ฆฌ๊ณ 3์ด๊ฐ ์ง๋๋ฉด A์ฌ์ฉ์์ ์์ฒญ์ DB ์๋ต์ ์๋ตํด์ค๋ค. ์ฆ ๊ธฐ๋ค๋ฆฌ๋ ์๊ฐ ๋์ ํ ์ ์๋ ์ผ๋ค์ ์ฐพ์์ ํด์ค๋ค
์ฆ ๋น๋๊ธฐ ์๋ฒ๋ ์ค๋ ๋ ํ๋๋ก ๋๋ฆฌ๋๋ฐ ๋์ ๋๊ณ ์๋ ์๊ฐ์ด ์๊ณ ๋ฐ๋ผ์ ๋ฌด์ฒ ๋น ๋ฅด๋ค.
๋ง์ฝ ๋น๋๊ธฐ ์๋ฒ๋ฅผ ์ฌ์ฉํ ๊ฑฐ๋ฉด db๋ ๋น๋๊ธฐ์ฌ์ผ ํ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋๊ธฐ์ด๋ฉด ์๋ฌด๋ฆฌ ์๋ฒ์์ ์ฌ๋ฌ ์์ฒญ์ ๋ฐ์ ์ ์๋ค ํด๋ db๊ฐ ๋๊ธฐ์ด๋ฉด ์์ฒญ์ ํ๋๋ง ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. Mongo๋ฅผ ์ ํํ ๋ ๋ค๋ฅธ ์ด์ ๋ ์ฌ๊ธฐ์ ์๋ค.
์ฝ๋๋ก ์ดํด๋ณด์
- ์ฐ์ MongoDB๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด application.yml ํ์ผ์ ์ค์ ๊ฐ์ ์ธํ ํด์คฌ๋ค.
spring:
data:
mongodb:
host: localhost
port: 27017
database: chatdb
- ์ปจํธ๋กค๋ฌ๋ 1:1 ์ฑํ , ๋จ์ฒด ์ฑํ , ์ฑํ ๋ฐ์ดํฐ ์ฒ๋ฆฌํ๋ ๋ฉ์๋ 3๊ฐ๋ก ๊ตฌ์ฑ
- ์ฌ๊ธฐ์ FLUX๋ "ํ๋ฆ" ์ด๋ผ๋ ์๋ฏธ๋ก ์ปจํธ๋กค๋ฌ์ ํด๋ผ์ด์ธํธ๊ฐ ์ปค๋ฅ์ ์ ์ ์งํ ์ ์๋๋ก ํด์ค๋ค.
@RestController
@RequiredArgsConstructor
@Slf4j
public class ChatController {
private final ChatRepository chatRepository;
/**
* 1:1 ์ฑํ
*/
//Flux: ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ๋ฆฌํด
@CrossOrigin
@GetMapping(value = "/sender/{sender}/receiver/{receiver}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Chat> getMsg(@PathVariable String sender, @PathVariable String receiver) {
return chatRepository.mFindBySender(sender, receiver)
.subscribeOn(Schedulers.boundedElastic());
}
//Mono: ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ๋ง ๋ฆฌํด
@CrossOrigin
@PostMapping("/chat")
public Mono<Chat> setMsg(@RequestBody Chat chat) {
chat.setCreatedAt(LocalDateTime.now());
return chatRepository.save(chat);
}
/**
* ๋จ์ฒด ์ฑํ
*/
@CrossOrigin
@GetMapping(value = "/chat/roomNum/{roomNum}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Chat> findByRoomNum(@PathVariable Integer roomNum) {
return chatRepository.mFindByRoomNum(roomNum)
.subscribeOn(Schedulers.boundedElastic());
}
}
- Mongo์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด์ค๋ Repository ์ฝ๋์ด๋ค.
- @Tailable ์ ์ปค์๋ฅผ ๋ซ์ง ์๊ณ ์ ์งํ ์ ์๋ค. ๋ฐ๋ผ์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ฌ ๋๋ง๋ค ์ปจํธ๋กค๋ฌ๋ก ์ด๋ ๊ฐ๋ฅํจ
- FLUX๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ์ ์๋ค.
- ํด๋ผ์ด์ธํธ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ๋ SSE ํ๋กํ ์ฝ์ ์ฌ์ฉํ๋ค.
public interface ChatRepository extends ReactiveMongoRepository<Chat, String> {
// Flux (ํ๋ฆ)
// ๋ฐ์ดํฐ๋ฅผ ํ๋ ค์ ๊ณ์ ๋ฐ๊ฒ ๋ค.
// Response ๋ฅผ ์ ์งํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ๋ณด๋ผ ์ ์๋ค.
//๊ฐ์ ๋ฐฉ์์ ์ฑํ
ํ๊ณ ์๋ ์ฌ์ฉ์ ์กฐํ
@Tailable
@Query("{ roomNum: ?0 }")
Flux<Chat> mFindByRoomNum(Integer roomNum);
}
์ ์ฝ๋๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด๋ฉด ์๋์ ๊ฐ๋ค
(๋ฒ์ธ)
ํ๋ก ํธ ๋ถ๋ถ์ ์ธ๋ถ์ js๋ฅผ ์ฌ์ฉํด ๋ฐ๋ก ๊ตฌํํด๋์๋ค. ๋ผ์ด๋ธ ์๋ฒ๋ ๊ธฐ๋ณธ์ ์ผ๋ก 5000ํฌํธ๋ฅผ ์ฌ์ฉํ๊ธฐ 8080ํฌํธ์๋ cors์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ๋๋ฌธ์ ์ปจํธ๋กค๋ฌ์ ์ด๋ ธํ ์ด์ ์ผ๋ก ๊ฐ๋จํ๊ฒ cors์๋ฌ๋ฅผ ํด๊ฒฐํด์ฃผ์๋ค.
์ฒ์์ ์๋์ ๊ฐ์ด WebConfigurer ์์ cors์๋ฌ๋ฅผ ํด๊ฒฐํด์ฃผ๋ ค ํ์ง๋ง netty ์๋ฒ๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์ ์ด ๋ฐฉ๋ฒ์ผ๋ก๋ ์คํจํ๋ค.
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://front-server.com");
}
};
}