ETC/한화시스템

한화 시스템 부트 캠프 20주차 회고

디아쿠 2024. 9. 24. 00:13

되길 바라며...

 

안녕하세요 나름 열심히 살고 있는 아쿠입니다. 또 못 지키게 되었지만 이젠 제가 배우고 있고 현재 하고 있는 프로젝트를 나열하는 곳이니 ,,, 재밌는 것은 덜 하,,,지 않을까요? ,,,

 

앞으로 잘 지켜보도록 하겠습니다 ,,, 오늘은 두 편을 업로드 할 예정입니다. 그래서 순서를 지키기 위해서 일단은 저번 19주차에 이어서 채팅에 대해서 말씀 드리도록 하겠습니다.

 

저번 ` ConsumerConfig.GROUP_ID_CONFIG 에러` 가 뜨게 되어 말씀 드린 적이 있는데 해결 방법은 결국 2번인

2. application.yml 에 group_id를 설정해 줄것 <- 으로 해결하게 되었습니다. 

나름 당당하게 다른 방법을 찾아오겠다고 한 것 같은데 이 방법이 ,, 가장 나쁘지 않을 것 같아서 채택하게 되었습니다.

 

현재 채팅 구현은 끝난 상태입니다.

채팅으로 구성 되어 있는 api 명세서입니다.

 

 

채팅을 하게 되면서 저는 일단 스톰프와 카프카에 대한 이해가 필요하다고 생각이 들었습니다.

이 기능을 활용하여 구현을 했고, 현재 프론트와 연결만 남은 상태입니다.

 

  1. 구독/발행 기반의 STOMP
  2. MessageBroker로 Kafka

이 두가지를 오늘 중점적으로 말씀 드리고, 같이 정리하면서 다시 공부하는 시간을 가져보려고 합니다 ,, ! 

저는 일단 제가 만든 로직에서 어떤식으로 진행이 되는지에 대해서 파악 하려고 했고

메세지를 보내는 구조

 

요청을 어떻게 하고, 파일을 받을 때는 kafka로 전송하는 것이 적합하지 않고 비효율적이기에 s3를 사용해서 url을 넘겨주는 형식을 사용하게 되었습니다. 파일 크기에 대한 문제도 있고, kafka는 낮은 지연 시간과 높은 처리량을 보장하도록 설계되어 있는데 파일을 직접 메세지로 전송하게 되면 처리 속도가 저하되고, 전체적인 성능 또한 낮아질 수 있습니다.

그렇기에 위와 같은 형식을 구성하게 되었습니다.!

 

현재 받는 파일 데이터

 

파일 데이터는 이렇게 받아오도록 처리 했습니다. s3로 저장하게 되어 url을 받아오는 형식으로 나타낸 postman 테스트 결과입니다

 

이제 어느정도 어떤식으로 구성 했는지 말씀 드렸으니 stomp와 kafka를 왜 사용하게 됐고, 동작 원리가 어떻게 되는지에 대해 말씀 드리겠습니다.

 

Q. WebSocket으로도 충분히 구현 가능한데 왜 stomp를 쓰나요?

저도 왜 STOMP를 사용하는지에 대해 의문을 가지게 됐고, 사용후에 이점을 알게 됐습니다.
일단 WebSocket이 제공하지 않는 메시징 프로토콜 기능을 보완하기 위해 stomp를 사용하는 것입니다.
1. WebSocket은 기본적으로 메세지를 전송하는 파이프라인 역할만 하고, 전송 되는 데이터에 대한 구조나 관리 방식을 제공하지 않습니다. 이는 개발자가 직접 메세지 형식을 정의하고 구현해야 합니다.
2. Stomp는 주제 기반(pub/sub) 모델을 통해 다수의 클라이언트가 특정 topic을 구독하고, 해당 topic에 메세지를 발행할 수 있게 합니다. 예를 들어 특정 채팅방에 있는 사용자들만 해당 채팅방에 보내진 메세지를 받을 수 있게 라우팅 처리를 할 수 있습니다.

이러한 이점 때문에 stomp를 사용합니다. 

 

여기에서 stomp는 실시간으로 메세지를 전송하지만, 일시적인 네트워크 오류나 연결 문제로 인해 메시지가 손실될 수 있습니다. Kafka는 메시지를 브로커에 저장하고 컨슈머가 안전하게 데이터를 읽을 수 있도록 설계되어 있어 메시지 손실을 방지하고 신뢰성을 제공합니다. 그렇기에 kafka와 stomp를 함께 사용하는 것입니다.

 

zamezzz 블로그 참고

 

- Publisher로 부터 전달받은 메세지를 Subscriber에게 메세지를 주고 받게 해주는 중간 역할을 하는 게 Message Broker 입니다.

- Message Broker는 메세지를 분류하고 전달하는 역할을 수행하며 pringboot를 사용하여 이미 구현된 STOMP Simple Broker를 통해서 빠르게 개발이 가능하다는 장점이 있습니다.

 

여기에서 Memory Brocker를 사용할 때 세션을 수용할 수 있는 크기 제한이라던지, 장애 시 메시지 유실의 문제를 해결 해 주기 위해 외부 브로커인 Kafka를 사용하는 것입니다.

 

< 메세지 브로커의 동작 방식 >

예를 들어 1,2,3,4,5,6 라는 유저가 A 방에 입장하게 됩니다.

1이 A방에서 채팅을 전송하면, A방 메세지 브로커가 메세지를 받게 됩니다.

A방의 메세지 브로커가 A방을 구독한 나머지 2,3,4,5,6 유저들에게 메세지를 전송하게 됩니다.

 

이렇게 이해 하면 편합니다 ,, ! 

 

@Configuration
@EnableWebSocket
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat")
                .setAllowedOriginPatterns("*") // 모든 도메인에서의 CORS 허용
                .withSockJS();
        registry.addEndpoint("/note")
                .setAllowedOriginPatterns("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // SimpleBroker로 두 개의 경로를 한 번에 설정
        registry.enableSimpleBroker("/sub", "/topic/note");
        registry.setApplicationDestinationPrefixes("/pub", "/app/note");
    }

 

현재 WebSocketConfig를 이렇게 구성 해 두었습니다.

STOMP기반 구현을 하기 위해서는 WebSocket 관련 설정 클래스를 추가해야합니다.

쉽게 말 하면 WebSocket 연결을 요청할 주소와, pub, sub를 요청할 주소를 설정해주는 곳이라고 생각하면 됩니다.

 

@EnableWebSocketMessageBroker = 메세지 브로커가 지원하는 WebSocket  메세지 처리를 활성화

 

configureMessageBroker() =  메모리 기반의 Simple Message Broker를 활성화 하는 것입니다. 메세지 브로커는 /sub로 시작하는 주소의 Subscriber들에게 메세지를 전달하는 역할을 하게 되고, 클라이언트가 서버로 메세지를 보낼 때 붙여야하는 prefix를 지정합니다. 저는 /pub 으로 지정했습니다. 

 

registerStompEndpoints = 기존의 설정과 마찬가지로 HandShake와 통신을 담당할 Endpoint를 지정하는 곳입니다. 클라이언트에서 서버로 WebSocket 연결을 하고 싶을 때 /chat 으로 요청을 보내도록 구성 했습니다.

 

@MessageMapping = 클라이언트가 Send 할 수 있는 경로입니다. WebSocketConfig에서 등록한 /pub 과 메세지를 보내는 곳의 경로가 합쳐지게 됩니다.

    // 메세지 전송
    @MessageMapping("/room/{chatRoomId}/send")
    public void sendMessage(@Payload SendMessageRequest request) {
        Long senderId = request.getUserId();
        messageService.sendMessage(request.getChatRoomId(), request, null, senderId);
    }

저는 메세지 전송 컨트롤러를 이렇게 구현 해 뒀는데, 위의 말과 결합하면

/pub/room/{chatRoomId}/send 의 경로로 메세지를 전송하게 되는 것입니다.

 

이를 통해서 메세지를 보낼 수 있게 됐고, Kafka는 메시지를 저장하고 처리하는 메시지 브로커 역할을 합니다.

 

클라이언트 -> stomp -> 서버

서버 -> kafka 토픽 -> kafka 소비자

 

kafka에 저장된 메세지를 다양한 소비자들이 읽고 처리하게 됩니다. 

 

오늘 성공한 stomp 통신과 kafka 처리 화면

 

간단하게 프론트를 만들어서 통신이 되는지 확인 해 보았습니다. 가린 것은 실명을 ,, 보호하기 위해 (?) 열심히 칠했습니다...

 

오늘은 여기까지 하겠습니다,,,! 

 

감사합니다 ,, ! 

 


 

깨알 같은 일상 얘기 ,, ❤ ❤

저희 멘토님이 사주신 토마토 바질 소르베 ,,, jmt

 

교육장 뒤에 카페가 있는데 토마토와 바질을 ,, 왜 섞어? 하는 마음에 시켜보았습니다 하지만 너무너무 맛있었어요 ,, 

술 먹었을 때 해장 될 거 같은 이 마음 (?) ,, 아 술 먹고 싶다.

 

강사님이 내신 책 ❣

 

강사님께서 책을 내셨습니다 ,, 저도 예전에 데이터 공부를 할 때 Do it! 책을 읽은 적이 있는데요 ,, 여기서 보니까 너무 신기하더라고요 책 내에는 이해하기 쉬운 그림과, 설명이 적혀 있고 실습형 네트워크 입문서기 때문에 따라하면서 익힐 수 있었어요 ,, !

강사님께 책에 싸인도 받고 덕담도(?) 적어주셨습니다. 하하. https://www.youtube.com/@ddarahakit 저희 강사님 유튜브 주소인데, 가끔 강사님이 어느 강의를 올리셨나 하고 들어가보곤 합니다 ,, 근데 댓글들이 다 찬양하는 댓글이 위주다보니 사람들 귀는 다 같구나 생각이 들었습니다. 저희 강사님이 최고 최고 최고 ,,, !!

 

짜잔 ~ ! !

 

2주 전에 적은 제 회고록이 우수 회고록이 되었습니다. 두 번째로 받는 선물인데요 ,, 앞으로 더 열심히 해서 최초 3회 우수 회고자가 되도록 하겠습니다 ,,,(매번 회고 쓰면 매니저님께 달려가서 회고 썼다고 자랑합니다 ,, 브이브이) 밀리지나 마라 ,, 이 글을 벌써 2시간 째 적고 있습니다 ,,, 21주차는 내일 적어야겠어요. 내일을 위해 오늘은 여기까지 ! 감사합니다 🥰

 

 

다들 오늘도 행복하세요 >~<

728x90