티스토리 뷰

RabbitMQ

Message Broker

HTTP는 단방향 단일성 통신

  • 클라이언트가 명백하고, 서버가 명백함
  • 클라이언트가 서버에 요청을 보내면, 서버는 클라이언트에 응답을 돌려줌 (클라이언트와 서버의 역할이 명백하게 분리)
  • 서버측에서 한 번 응답을 보내고 나면 http 요청-응답의 관계가 끝나게 됨 (단발성)
  • 어느 한 쪽이 요청을 보내면, 반대쪽에서 요청을 보내라고 요청할 수는 없음 (단방향)

Message Broker

  • 메시지 기반의 통신을 위해 활용하는 부수적 소프트웨어(Middleware)의 일종
    • 미들웨어: 그 자체로서 기능하기 보다는 다른 소프트웨어에 추가적인 기능을 부여하기 위해서 사용하는 소프트웨어
  • Message Queue를 구현해 놓은 것

Publish Subscribe Message Pattern

 

RabbitMQ

대표적인 Message Broker중 하나

2가지 작동 방식이 있음

메시지를 받는 서버 쪽에서는 항상 queue를 선언하게 됨

Exchange 우체국 Queue 우편함 Message 편지 와 같은 관계

queue는 특정한 exchange에 bind됨(소속됨) > RabbitMQ의 클라이언트 프로그램들은 queue에 직접 메시지를 적재하는 것이 아닌, exchange에 메시지를 적재. exchange가 어떤 queue로 메시지를 보낼지 결정하는 구조

 

메시지 기반 비동기 통신

 

 


Message Broker 활용

 


Redis

Key - Value Databse

Redis(Remote Dictionary Server)

  • Dictionary: Key-Value 형식으로 데이터를 저장하는 Collection

Key-Value 형식으로 데이터를 저장하고 꺼내쓰는데 용이한 데이터베이스의 일종

Redis의 특징

In-Memory: 휘발성 데이터 (휘발성 데이터를 담기 위해 고안된 데이터베이스)

NoSQL: SQL을 이용한 조회를 하지 않음 (문자열로 된 키 값을 전달하면 그 키에 저장되어 있는 값을 돌려주는 역할의 데이터베이스로, SQL이 필요하지 않음)

외부 캐시 또는 Message Broker로 활용

로그인 요청이 들어왔을 때, 해당 요청을 내부에 저장하지 않고, 세션 아이디는 클라이언트에서 관리하니, 세션아이디를 키값으로 레디스에 저장하는 시나리오

클라이언트의 브라우저에는 레디스에 저장되어 있는 로그인 정보에 대한 정보가 키-밸류 형태로 저장되어 있음

다음 요청이 다른 서버로 간다고 해도 사용자가 누구인지 문제 없이 확인 가능

프로듀서(왼쪽 서버)가 메시지 큐에 요청을 적재 (요청을 보낼 때 어떤 요청을 보냈는지에 대한 구분자 requestKey를 보냄)

메시지 큐에서 요청을 확인

컨슈머(오른쪽 서버)에서 요청을 확인

요청을 확인한 결과를 돌려줘야 하는데, 결과를 돌려주는 방법으로 레디스를 활용

레디스에 처리가 완료된 데이터를 적재해서 요청했던 서버에서 레디스에 있는 데이터를 조회해서 비동기 통신을 구현 (레디스에서 조회할때도 requestKey를 가지고 조회)


WebSocket

application layer상에 정의된 통신규약

WebSocket이란?

HTTP는 단방향 단일성 통신 > 서버에서 클라이언트로 우선적으로 데이터를 보낼 수 있는 방법이 없음

클라이언트와 서버가 좀더 자유롭게 메시지를 주고받기 위한 방법들(양방향 통신)을 연구, 그러한 방법들 중 하나가 웹소켓

웹소켓: 양방향 통신을 구현하기 위해 가장 흔하게 사용되는 통신 규약 중 하나

연결이 이루어진 후에는 한 쪽인 연결을 종료하기 전까지 메세지를 지속적으로 주고받을 수 있는 통신 규약

하나의 서버 엔드포인트에 여러 개의 클라이언트와 연결 가능

이런 점을 활용해 채팅 어플리케이션을 만드는 데 많이 사용함

클라이언트에서 Handshake라는 요청을 보냄

Handshake 요청: HTTP 요청의 일종 (Upgrade: websocket 헤더가 존재)

해당 헤더가 존재함으로써 서버는 클라이언트가 웹소켓 통신을 하려고 한다는 것을 판단

웹소켓 연결이 이루어지고 메시지를 주고받는 과정에서 총 4가지 일이 발생

1. onOpen(): 연결

2. onClose(): 연결 종료

3. onMessage(): 양방향으로 통신

4. onError(): 에러 발생

위의 4가지 사건(event)을 기준으로 클라이언트와 서버의 프로그래밍이 진행됨 (Event Driven Programming)

Event Driven Programming: 어떠한 event의 발생과 해당 event의 handling을 통해서 구현해나가는 프로그래밍 방식

웹소켓은 대표적인 event driven programming

WebSocket / STOMP

웹소켓은 오고가는 메시지의 형태가 어떤 형태의 데이터이든 상관없음 > 데이터의 해석이 어려움

cf) HTTP는 request header, status line 등의 배치가 정의되어 있는 통신규약이나, 웹소켓은 handshake를 하고 난 후에 주고받게 되는 데이터의 형식에는 규약이 없음 > 따라서 주고받는 데이터가 명백하게 무엇인지 개발자가 먼저 알고 있어야 하는 단점이 있음

왼쪽: HTTP에서 사용하는 통신 규약

오른쪽: 비슷한 형태의 데이터 규약을 정의해둔 subprotocol. Frame이라고 부르며, 서로 주고받는 메시지의 형태로서 정의해둔 서브프로토콜을 STOMP라고 부름

STOMP (Simple/Streaming Text Oriented Messaging Protocol)

웹소켓 위에서 추가로 사용하는 통신 규약

STOMP를 이용함으로써 비교적 편하게 어떠한 형태의 데이터인지 예측 가능

HTTP: 패스 디자인을 잘 해서 경로에 따라 어떤 자원이 존재하는지가 명백하게 드러나도록 설계하는 것이 RESTful한 개발

STOMP: STOMP Frame 형식의 예시. Destination이란 WebSocket 자체에 연결하기 위한 경로와 별도로 내부적으로 추가적인 경로를 설정하는 것.

 

WebSocket Chatting

 

function connect() {
            getRoomName();
            let socket = new SockJS('/ws/chat');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                console.log('Connected: ' + frame);
                stompClient.subscribe(`/receive-endpoint/${roomId}`, function(message) {
                    showMessageOutput(JSON.parse(message.body));
                });
            });
        }

SockJS: websocket을 사용할 때 JS에서 많이 사용하는 라이브러리

stompClinet.connect(): websocket 연결이 처음 구성 되었을 때를 의미

function(frame): websocket 기준으로 하나의 메시지, STOMP 기준으로 frame을 받게 되었을 때 그 메시지를 나타내는 변수

console.log부터~: 그 메시지를 받을 때 어떻게 반응할 것인지에 대한 onMessage() event handler

  • stompClinet.subscribe(): /receive-endpoint라는 destination에 구독. /receive-endpoint로 들어오는 메세지들에 대해 들을 수 있게 됨. 이 HTML을 로드한 쪽은 /receive-endpoint로 보내진 메시지들을 듣도록 설정되는 것
        function sendMessage() {
            let message = document.getElementById('message').value;
            stompClient.send("/send-endpoint/ws/chat", {},
                JSON.stringify({
                    'roomId': roomId,
                    'sender': nickname,
                    'message': message
                }));
        }

메시지를 보낼 때 사용하는 함수

stompClient.send(): endpoint 설정. /send-endpoint/ws/chat destination을 통해서 요청을 보내게 된다.

JSON.stringify(): JSON 객체처럼 보이는 것을 문자열로 변환해서 전송

 


WebClient

WebClient란?

일반적으로 평소 프로그래밍 함수 호출을 하면 함수가 처리되고, 그에 대한 결과를 가지고 프로그램이 다음 단계의 코드를 실행함.

리액티브 프로그래밍은 요청이 처리중인 와중에도 해당 쓰레드에 대한 자원을 해소하고 쓰레드가 다른 요청을 처리할 수 있도록 자유롭게 풀어줄 수 있음.

 

 

'Java > project lion JSB the origin' 카테고리의 다른 글

Ch.10 Spring Cloud  (0) 2022.04.05
Ch.8 Spring Security  (0) 2022.03.20
Ch.7 Spring Boot 기능활용 (2)  (0) 2022.03.13
Ch.6 Spring Boot 기능활용(1)  (0) 2022.03.04
Ch.5 CRUD & Data (2)  (0) 2022.03.01
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함