![[실전개발] Redis Pub/Sub를 활용한 실시간 알림 구현 with FastAPI 대표 이미지](https://i.ytimg.com/vi_webp/I6ioHc1yspg/maxresdefault.webp)
[실전개발] Redis Pub/Sub를 활용한 실시간 알림 구현 with FastAPI
요약
FastAPI와 Redis Pub/Sub 기능을 연동하여 실시간 시스템 알림 구현 방법을 다룹니다. 특히 FastAPI의 비동기 루프를 활용한 구독 커넥션 관리 패턴과 브라우저와의 통신을 위한 Server-Sent Events (SSE) 기술 사용법을 설명합니다. 이 과정에서 Redis Pub/Sub이 제공하는 느슨한 결합(Decoupling) 구조와 실무 구현 시 주의할 점들을 심도 있게 다룹니다.
핵심 포인트
- Redis Pub/Sub은 발행자-채널-구독자로 구성된 1:N 브로드캐스팅 패턴입니다.
- FastAPI의 비동기 루프를 활용하여 구독 커넥션을 효율적으로 관리하는 실무 패턴을 배웁니다.
- 브라우저와의 실시간 통신에는 SSE(Server-Sent Events) 기술이 사용됩니다.
- Redis Pub/Sub 구현 시, 일반 명령어용 연결과 전용 구독 연결을 분리해야 합니다.
Video: [실전개발] Redis Pub/Sub를 활용한 실시간 알림 구현 with FastAPI
Channel: 코딩하는기술사
Duration: 28m 54s
Source: subtitle (auto, ko)
Transcript:
네, 안녕하세요. 이번 시간에는이 패스트 API하고 레디스의 팝섭 기능을 연동해서이 실시간 시스템 알림을 구현해 보겠습니다. 자, 오늘의 학습 목표입니다. 어, 저희가 지난 그 섹션 4에서 레디스 폼서 기능을 알아보면서 레디스 CLI에 가지고 테스트를 해 봤죠. 근데 실무 환경에서는 CLI 가지고 뭐 구독을 하거나 뭐 발행하거나 이렇게 잘하진 않죠. 어 실제로는이 패스트 API 같은 백핸드 서버가 레디스와 연동해서 팝섭을 구현해야 됩니다. 그래서 이번 실습 시간에는 패스트 API와 레디스의 팝섭을 연동을 해 볼 겁니다. 자, 패스트 API의 비동기 루프를 활용해서 어, 이렇게 구독 커넥션을 효율적으로 관리하는 실무 패턴도 배우고요. 어, 그리고 부과적으로이 브라우저와 통신하는 부분은이 서버 센터 이벤트 요거 사용 한번 해 볼 겁니다.이 이 SSE 기술은이 HTML 5에 도입된 기술이죠. 어, 서버가이 HTTP 연결을 유지한 채로 데이터를 브라우저로 실시간으로 푸시해 주는 단방 스트리밍 기술인데요. 어,이 기술은 현재이 법섭하고는 전혀 무관한 기술이죠.
다만 저희 이제 샘플에서는 조금 더 직관적으로 시뮬레이션 하기 위해서이 브라우저가 패스트 API로 요청하면 패스트 API가 레지스로 구독해서 그 메시지를 실시간으로 브라우저까지 보여 주는 걸 어 테스트하기 위해서 이렇게이 기술을 사용하는 것이고요. 보통이 브라우저가 웹 어플리케이션으로 요청하는 기술이 폴링 그리고 SSE 그리고 웹 소켓이 있죠. 거의 뭐 90% 이상은 폴링을 사용하는데요. 저희는이 서버센터 이벤트를 사용해서 실시간으로 구독한 메시지를 브라우저 땅까지 내려보내 보겠습니다. 참고로 이번 시간에이 서버센터 이벤트가 주는 아닙니다. 다만 기본적인 사용법은 설명을 드릴 겁니다. 자, 먼저 실습을 하기 전에 어 팝섭 개념을 다시 한번 짚어 보겠습니다. 자, 여기 아래 개념들을 보시죠. 이렇게 중앙에 레디스가 있고요. 퍼블리쇼 즉 발행자가 있습니다. 그리고 서버스크라이브 구독자가 있죠.이 이 퍼블리셔가 레디스를 향해서 레디스의 특정 채널로 메시지를 발행하면 실시간으로 여러대 구독자에게 메시지가 전송되는 기능입니다.
즉 발행자 그리고 구독자 그리고 중간에 채널. 자, 이렇게 1대 n으로 브로드캐스팅 하는 방식의 통신 패턴인데요. 어, 이렇게 구현을 하면 어,이 퍼블리셔와이 서버 스크립트간에 직접적인 연결 없이 통신이 가능하죠. 중간에 레디스만 경류하는 거죠. 어, 이걸 우리는 늦슨한 결합이라고 합니다. 즉 두 개가 디커플링 되어 있죠. 즉 연결이 되어 있지 않은 상태에서 어떤 이벤트를 전달하고 전달받을 수 있는 느슨한 구조인 거죠. 이렇게 하면 서브스크라이브가 얼마든지 늘어나도 퍼블리셔와 서로 상관없이 이렇게 확장할 수 있는 거죠. 자, 근데이 팝서업을이 백엔드에서 구현하려면 약간 까다로워요. 우리가 이전 시간에 해봤던 그 CLI 가지고 법섭을 테스트하는 건 굉장히 심플하거든요. 근데 실제이 자바나 뭐 패스트 API 노드에서 레디스 팝섭을 구현할 때는 약간 주의해야 될 사항이 있습니다. 자, 그게 뭐냐면 여기 한번 보겠습니다. 어, 일반적인 레디스 명령, 겟셋 같은 이런 레디스 연동은 어플리케이션이 레디스로 요청하면 바로 응답이 완료되는 그런 구조죠.
하지만이 구독이라는 것은이 서버스크라이브 실행하면이 어플리케이션이 서버스크라이브를 하면 레디스가 발행할 때까지 메시지를 기다리는 상태 즉 블로킹 상태가 되면이 연결은 메시지 수신 전용 모드가 되는 겁니다. 그래서이 업에 사용한이 연결에는 일반적인 레지스 명령어겟셋 같은 일반 레지스 명령어를 날릴 수가 없어요. 그래서 어 실무에서는 이렇게 해결하는데요.이 어플리케이션이 레지스와 연동할 때 일반적인 셋 겟 명령을 내리는 커넥션은 그대로 두고 별도의 팝선만을 위한 전용 연결을 사용하는 겁니다. 자, 여기 보시면 어, 일반 연결 즉 개셋 데이터 처리용과 팝섭 전종 커넥션을 둬서이 팝섭 전용 커넥션은이 레지스터가 발행하는 그 메시지를 대기하고 처리하는 용도로만 사용하는 것이죠. 자, 우리 여제에서는이 패스트 API 비동기 루프 혹은 별도 데스크를 통해서 구현하는데요. 우리도이 비동기 루프로 법 메시지를 지속적으로 수신하도록 구현해 볼 겁니다. 자, 우리가 실습을 해 볼 저녁 공지 시스템입니다. 자, 서버가 이렇게 여러 돼 있고요.이 서버들은 모두 중앙에 레지스를 구독하고 있습니다.
그리고 어 브라우저 즉 클라이언트가이 서버들에 다 연결을 하고 이때 서버 센터 이벤트 연결 통로를 만들 겁니다. 그리고 특정 서버가 메시지를 레지스에 발행하면 레지스는이 팝서 채널을 통해서 모든 구독하고 있는 서버들에게 즉시 메시지를 전송할 겁니다. 어, 이렇게 구독하는 서버들은 메시지를 받으면이 열려 있던 서버 센터 이벤트 연결 클라이언트 브라우저에게 발행한 메시지가 실시간으로 전달되는 샘플을 만들어 볼 겁니다. 어, 참고로 메시지 발행은이 구독하고 있는 특정 서버들 중 한 대가 발행할 수도 있지만 백단에 어떤 관리툴를 통해서 발행할 수도 있겠죠. 아니면 뭐 레지스 CLI를 통해서 관리자가 해당 채널에 메시지를 발행할 수도 있을 겁니다. 그러면 실시간으로 구독하고 있는이 패스 API 어플리케이션에게 즉시 전송이 되는 구조입니다. 자, 이런 구조는 우리 샘플에서는 뭐 전혀 공지라는 가상의 시나리오를 잡았는데요. 어, 이런 구조는 굉장히 많은 곳에 사용될 수 있죠. 뭐 이렇게 서버가 여러 분산돼 있는 환경에서 중앙에 메시징 시스템을 둬서 채팅 같은 걸 어떤 한 서버가 전송하면 모든 서버에게 이렇게 실시간으로 전송할 수도 있을 테고 아니면 뭐 분산 락을 구현할 때도 어떤 서버가 자기가 분산락을 걸어 놓고 분산락을 해제할 때 이렇게 해제하면 즉시 알림을 줄 수도 있겠죠.
어, 또 아니면 뭐이 클라이언트가 없어도 되고요. 어떤 시나리오에서는 이렇게 서버 시스템에서 어, 뭐 캐시 무효화 같은 것도 어떤 서버가 뭐 사용자 캐시를 다들 똑같이 이렇게 로컬 캐시로 유지하고 있는데 어떤 서버가 사용자 정보를 수정하는 걸 RDB에 수정하고 나서 개시를 갱신시키기 위해서 다른 서버들에게 알려 줄 필요가 있잖아요. 그때도이 레지스터를 통해서 알려줘 하면 이렇게 구독하고 있는 다른 서버들에게 알림을 전송하고이 서버들은 자신의 로컬 캐시를 갱신하든지 뭐 기존 캐시를 무효화든지 그런 걸 할 때도이 레지스 알림 시스템을 사용하면 좋습니다. 자, 이제 본격적으로 코드를 보겠습니다. 자, 먼저 패스이 코드인데요. 파일 이름은 퍼서버. 으로 나중에 저장하고 테스트해 볼 겁니다. 자, 기본적으로 계속 설명드리는 부분이죠. 네. 그 레디스 비동기 모듈을 사용합니다. 그리고 어 라이프스펜를 이용해서 패스트 API에서 서버가 시작할 때 레디스 연결을 만들고이 서버가 종료될 때 안전하게 연결 해제하는 코드를 작성하는데요.
이것도 계속 우리 백핸드 실무 패턴에서 똑같이 계속 구현하고 있는 부분이죠. 그리고 나서 섭섭 채널을 정의합니다. 자, 이게 채널 이름을 시스템 콜론 노티스로 어 공지 사항 채널 명을 미리 지정해 둡니다. 어, 그리고이 엔드 포인트는 어, 폼 수업하고 상관없긴 한데요. 우리가 테스트를 위해서 프론트에 테스트 페이지를 하나 만들 겁니다. 아까 그 구조도에서 본 것처럼 그 클라이언트는 그 서버와 서버 센터 이벤트 통신 경로를 열어두고 메시지를 전달받을 건데요. 그 역할을 하는 HTML 파일을 베스트 API에서 이렇게 서비스 하기 위해서 정의한 엔드포인트입니다. 즉 슬래시 법섭하면이 HTML이 반환되는 거죠. 자, 그다음 자, 엔드포인트입니다. 자, 퍼블리시 노티스를 하면이 엔드 포인트를 호출하면 레디스로 메시지를 발행시킵니다. 자, 우리는 테스트할 때 스웨그에서이 엔드 포인트를 호출해서 메시지를 발행시켜 볼 텐데요. 자, 로직은 간단합니다. 앞서 생성한 레지스 연결 풀로부터 레지스 연결 객체를 하나 가져옵니다.
자, 여기서는 일반 레지스와 연동하는 연결 객체를 가져오는 거죠. 아직까지는 폼서 전용 연결 객체가 아니라 레지스의 일반적인 명령을 내리는 레지스 연결 객체를 이렇게 가져옵니다. 그리고 나서 이렇게 퍼블리시 메서드로 앞서 정의한 채널 이름으로이 메시지를 발행하는 것이죠. 그리고 발행하고 나서 석세스를 반환하고 현재 수신 즉 구독 중인 구독수를 반환시킵니다. 자, 발행은 되게 심플하죠. 자, 그리고이 스트림 노티스이 엔트 포인트가 이제 핵심인데요. 클라이언트로부터 어,이 요청을 받으면 서버센터, 이벤트, 연결 통로를 만들고 레디스의 구독을 통해서 어, 메시지가 들어오면이 클라이언트 SSE 통로로 메시지를 실시간으로 전송하는 역할의 자, 여기 안에서도 이렇게 함수가 정의되어 있는데요. 이것은이 레지스에서 받은 메시지를이 서버 센터 이벤트에 계속 생성해서이 보내기 위해서 필요한 비동기 제너레이터 함수입니다. 어, 이렇게 해야지 그 SSE의 그 스트리밍 리스폰스 쪽으로 반환이 되는데요. 즉 SSE는 데이터를 계속 만들어 주는 함수가 필요해서 이런 정의가 필요한 겁니다.
즉 연결을 유지하고 있는 상태에서 데이터가 생길 때마다 전송을 해야 되기 때문에 이렇게 패스트 API에서는 이런 형태의 제너레이터 함수 구현이 필요합니다. 어이 부분은 그 레지스 팝섭하고온 전혀 무관한 SSE를 위한 코드입니다. 자 그리고 본격적으로 레디스의 퍼섭 전종 개체를 하나 가져옵니다. 자 앞서 라이프스펜에서 만든 레지스 연결 풀에서 팝선만을 위한 전용 연결 객체를 하나 가져오는 거죠.이 이 부분이 앞서서 말씀드린 그 연결 객체를 따로 나눠서 전용 객체를 만드는 부분입니다. 그리고 나서이 앞에 어싱크 위드로 해서 어 객체가 생성되고 난 뒤에 이것이 다 사용되고 작업이 끝나면이 레디스 연결을 자동으로 반환하도록 하기 위해서 이렇게 어싱크 위드를 정의를 했고요. 이렇게 만든이 전용 객체를 가지고 팝서업 전용 객체를 가지고 구독을 하는 것입니다. 자, 이렇게 구독할 때 앞서 정의한이 채널 명으로 구독을 합니다. 자, 이렇게 구독을 하고 나서 이제 메시지를 대기를 해야 되는데요. 자, 이렇게 무한 루프로 메시지를 대기합니다.
이때 겟 메시지로 에디스로부터 발행되는 메시지를 대기하게 되는데요. 여기에서이 옵션을 트루로 설정하는 것은이 레디스가 메시지를 발행해서 이렇게 메시지를 전달할 때 어 실제 데이터만 주는게 아니라 뭐 서버스크라 un서버스크라ed 같은 그런 메타데이터도 같이 주거든요. 그래서 이런 메타데이터는 무시하겠다라는 설정으로 트루를 준 것이고요. 그리고 밑에이 if 조건도 어 메시지의 타입이 메시지이면 즉 다른 메타데이터는 걸러내고 실제로 데이터인 경우만 처리하기 위해서 입부 조건을 한 번 더 둔 것입니다. 자 결국 무한 루프를 돌면서 메시지를 받을 때까지 대기를 하고 또 여기 중요한 것이 겟 메시지로 메시지를 대기할 때 타임아웃을 줄 수가 있습니다. 현재이 소스에서도 타임아웃을 1초로 줬는데요.이 이 타임아웃이 없으면이 겟 메시지 하는 것은 계속 블러킹 상태로 머무르게 됩니다. 하지만 타임아웃을 1초를 주면 1초 동안만 메시지가 들어오는 것을 기다렸다가 메시지가 들어오지 않으면 넌을 반환하면서이 함수를 끝내게 됩니다.
어,이 타임아웃을 주지 않고 계속 블록된 상태로 해도 구현은 가능한데요. 보통 이렇게 타임아웃을 주는 이유는 이렇게 무한 루프로 계속 대기하면서 메시지도 1초 정도 대기해 보고 그 밑에 뭔가 어떤 상태를 한번 체크해서 뭔가 다른 로직을 구해내야 될 상황이 있을 수가 있거든요. 그래서 보통 실무에서는 이렇게 계속 기다리지 않고 타임아웃을 줘서 어느 정도 기다렸다가 빠져나갔다가 밑에서 또 다른 뭔가에 체크를 하고 다시 루프로 올라와서 다시 또 겟 메시지 해서 대기하는 형태로 구현하는게 많습니다. 현재 우리이 샘플 같은 경우에는 여기 보면 브라우저가 창을 닫고 나가면 계속 대기할 필요가 없잖아요. 현재 우리 샘플 로직에서는. 그래서 1초 동안 기다렸다가 메시지가 들어오든 뭐 들어오지 않든이 함수를 끝내고 나서 메시지가 안 들어와도이 함수를 끝내서 클라이언트 즉 브라우저의 상태를 한번 보는 거죠. 그 서버센터 이벤트로 연결돼 있는데 클라이언트가 그냥 떠났다면 더 이상이 로직을 실행할 필요가 없는 거죠.
그래서 클라이언트의 리퀘스트 디스커넥션으로 클라이언트가 떠났는지 확인하는 것입니다. 떠났으면이 루프를 빠져나가도록 하는 것이죠. 자, 그리고 이렇게 메시지를 받으면 서버센터 이벤트에 연결된 채널로 이렇게 데이터를 만들어서 반환시켜 줍니다. 어, 참고로 이렇게 일드 키워드로이 레지스에서 받은 메시지를 서버센터 이벤트 형식으로 브라우저에 정송하기 위해서이 스트리밍 응답으로 보내기 위해서 1년 일드 키워드를 사용하고 여기 밑에 스트리밍 리스폰스로 반환하는 겁니다. 이건 역시 그 레지스 팝섭하고 상관없이 자, 그리고이 코드는이 루프,이 무한 루프를 잠시 대기시키는 코드입니다. 자, 이렇게 아주 짧게라도 슬립을 걸어 주는 이유는이 루프가 이런 슬립 없이 과도하게 돌면 CPU를 어, 많이 사용할 수 있고이 이벤트 루프를 자기가 이렇게 독점할 수도 있거든요. 그래서이 루프에 의한 CPU 과사용을 방지하고 다른 비동기 작업의 어떤 실행 기회를 주기 위해서 이렇게 잠시 슬립시킵니다. 자, 그리고 파이널리에서는 어 작업을 종료하고 법섭 연결 객체를 이용해서 구독 해지를 하는 것이죠.
자, 이렇게 파일 문으로 파일 툴로 해서 무한 루프로 이렇게 계속 돌면서 겟 메시지 하면서 1초 타임아웃 1초로 가지고 1초 동안 대기했다가 메시지가 들어오면 이렇게 메시지를 만들어서 계속 전송하고 메시지가 들어오지 않으면 넌을 반환해서 메시지가 없으니까 다음번 루프로 또 올라가서 또 대기하고 이런 식입니다. 자, 근데 여기서 어 한 가지 말씀드릴게 있어요.이 이 법섭 연결이 객체 있잖아요.이 현재 우리 샘플 구조는 클라이언트 수만큼 즉 접속하는 브라우즈 수만큼 팝섭 연결 객체가 생성되도록 되어 있습니다. 근데이 실제 서비스에서는 보통 어 레디스이 구독을 소수에 연결 객체를 유지하고 이렇게 클라이언트한테 뭔가 전송하는 건 서버 내부에서 서버 내부의 어떤 로직에 의해서 처리하도록 하는 경우가 많습니다. 다시 말해서 현재 우리 샘플의 시나리오는 클라이언트가 접속을 하면 그 접속과 동시에 팝섭 전용 객체를 생성해서 구독 요청을 하고 겟 메시지로 대기를 하죠. 또 다른 클라이언트가 들어오면 또 똑같이 팝섭 객체를 생성하고 구독하고 또 이렇게 겟 메시지로 대기를 하는 구조죠.
근데 저희 샘플에서는 이렇게 그냥 직관적으로 클라이언트가 접속해서 이렇게 한 방에 발행까지 되는 걸 이렇게 메시지가 브라우저까지 실시간으로 이렇게 보여지는 걸 이렇게 보기 위해서 즉 직관적으로 이렇게 한 번에 하기 위해서 이렇게 구현을 하는 건데요. 어 일반적으로는 이런 식으로 구현은 잘 안 합니다. 이렇게 구현하면이 클라이언트가 즉 사용자가 엄청 많아질수록 여기에는 계속 팝서업 객체가 생성될 거잖아요. 그래서 보통이 법업 객체는이 서버 입장에서 뭐이 어플리케이션이 시작할 때라든지 아니면 어떤 특정한 조건을 만족할 때 아니면 특정한 이벤트를 받았을 때 법업 전용 객체를 만들어서 어떤 구독을 요청하고 메시지를 대기하는 형태를 구현을 많이 하고요. 메시지를 이렇게 받으면 자기한테 붙어 있는이 여러 클라이언트들한테이 메시지를 전달해 주는 것은 서버 내부의 로직을 가지고 처리하는 것이지 현재 우리 샘플처럼 연결할 때마다 서버 스크랩 하는 구조는 일반적으로 잘 안 씁니다. 저희는 샘플을 위해서 이렇게 한 거고요.
자, 그 말이 여기 있습니다. 어, 실무에서는 레디스 팝서 구독을 어플리케이션 시작시 생성 하고 서버가 종료될 때 구독을 해제하는 방식을 많이 운영합니다. 자, 소스를 설명할 때 다 말씀을 드린 부분인데요. 어, 한 번 더 이렇게 제가 다 정리를 해 놨는데 한 더요 부분만 좀 말씀드려 볼까요? 어 커넥션 독점 문제 계속 반복적으로 말씀드리는 건데요. 우리가 앞서이 라이프스에서 만든이 레지스 연결 풀은 현재이 패스트 API에 여러 API들이 공유하는 연결 풀입니다. 그래서이 풀에서 뽑아 가지고 연결 객체를 만들어서이 구독을 해 버리면 그 커넥션은 메시지 대기 전용이 되어 버려서 다른 일반적인 레디슨 명령을 처리할 수 없게 되죠. 그래서 어 항상이 법섭을 위한 전용 연결 객체를 따로 만들어서 사용해야 됩니다. 자, 이렇게 필요할 때마다 구독 정용 커넥션 객체를 할당마다 사용합니다. 이렇게 해서 커넥션 풀레에 다른 커넥션들을 방해하지 않도록 합니다. 자, 나머지는 뭐 이렇게 자동으로 해제하도록 하는 것과 밑에 어 매트 데이터 안 받는 부분 어 그리고이 SSE 관련된 처리 부분은 앞서 다 설명을 드린 것이고요.
여러분들이 직접 이렇게 나중에라도 헷갈릴 때 볼 수 있도록 다 이렇게 정리를 해 줬습니다. 아, 그리고이 SS 구현 그리고 어, 뭐이 부분은 좀 말씀드려 볼까요? 앞서이 부분도 말씀을 드린 건데요. 이렇게 어 어떤 어플리케이션 두 개가 직접 연결된 강한 연결 구조가 아니라 이렇게 중간에 메시지 시스템을 두고 퍼블리셔가 발행하고 서버스크라이버가 구독하는 이런 형태는 아주 느슨한 연결 즉 직접 연결돼 있지 않는 디커플링된 상태죠. 이렇게 하면 서로가 서로의 존재에 대해서 전혀 몰라도 그냥 자유롭게 메시지를 발행하고 어떤 메시지를 수신할 필요가 있는 서버만 또 구독 요청을 해서 자신의 일을 처리하면 되는 아주 확장성이 좋은 아키텍처가 되는 겁니다. 자, 이제 테스트를 위한 프론트 핸드 코드입니다. 어, 팝서 HTML 파일로 만들 거고요. 클라이언트 코드는 굉장히 심플합니다. 그냥 로딩 하자 말자 서버센터 이벤트 연결 통로를 만들어서 메시지를 대기하는 거죠. 자, 여기 보시면 어, 이렇게 SSE 연결 통로를 만들고 메시지가 올 때 반응하는 이벤트를 만들고이 이벤트로 메시지가 들어올 겁니다.
그러면 이렇게 이벤트 데이터로 메시지를 화면에 찍어 주는 겁니다. 뭐 클라이언트는 거의 뭐 하는 일이 없이 그냥 메시지 SS로 받아서 보여주는 역할입니다. 자, 클라이언트의 소스 설명도 이렇게 해 놨는데요. 요것도 한번 읽어 보시기 바랍니다. 뭐 계속 말씀드리지만 팝섭하고는 무관하지만 그냥 SSE 관련된 내용과 뭐 클라이언트에 소소한 구현 팁들이 이렇게 있습니다. 자, 이렇게 서버와 프론트 코드를 가지고 테스트를 해 볼 건데요. 우리는이 패스트 API 애플리케이션을 두 대를 띄울 겁니다. 포트를 다르게 해서 하나는 8,000번, 하나는 8,1번. 이렇게 해서 마치 두대 서로 다른 웹 어플리케이션이 있는 걸 가정할 겁니다. 그리고 중앙에 레디스를 공유해서 발행과 구독을 처리할 겁니다. 그리고 프론트 브라우저도 두 개 띄워서 어 이렇게 연결을 해서 직접 발행도 해 보고 또 발행한 걸 이렇게 구독도 해 보는 걸 테스트해 볼 겁니다. 자 그게 여기 설명이고요. 서버 두 개 띄우겠다. 서버 두 개 띄울 때는 패스트 API 띄울 때 유비콘으로 띄우죠.
이게 포트 다르게 해서 서로 다른 어플리케이션으로 띄울 겁니다. 그리고 브라우저에서도 이렇게 SS 채널로 메시지를 받는 엔드포인트로 이렇게 각자 접속을 해 볼 거고요. 그리고 메시지 발행은 스웨그 UI를 통해서 브라우저로 한번 전송해 볼 겁니다. 자, 조금 있다가 테스트를 해 보면 결과를 볼 수 있을 텐데요. 어,이 8,번과 8,1번 동시에 알림 메시지가 출력될 겁니다. 즉 레지스가 발행한 메시지를 보관하지 않고 즉시 모든 구독자에게 전송하는 거죠. 그리고 현재는 서버가 두 대인 것을 가정하지만 뭐이 서버들이 100대 1천대로 늘어나더라도 어 동일한 채널을 구독하고 있으면 모든 유저에게 실시간으로 메시지를 적각 보낼 수 있습니다. 다만이 구독자가 순간적으로 끊기거나 아니면 처리 장애가 발생하면 그 사이에 메시지는 복구되지 않고 유실될 수 있습니다. 우리 팝섭은 휘발성 메시지를 전송합니다. 한번 발행된 메시지는 그 당시에 받지 못했다면 그 이후에는 받을 수 없습니다. 메시지가 전혀 저장되지 않습니다. 자, 이제 실습을 직접 한번 해 보겠습니다.
먼저 이렇게 팝섭 서버. 파이썬 파일과 법t 파일을 만들겠습니다. 자, 이건 패스트 API 코드고요. 자, 이거는 테스트 클라이언트 페이지 코드입니다. 자, 이렇게 만들고 패스트 API 코드를 복사합니다. 그리고 붙여 놓고 어, 브론트 엔드 테스트 코드도 복사해서 자, HTML을 붙여 놓습니다. 자, 소스 코드는 다 설명을 드렸으니까 직접 띄워서 테스트를 해 보겠습니다. 어 저희는이 패스트 API 요거 똑같은 거 서로 다른 어플리케이션으로 띄우기로 했죠. 어 터미널 두 개를 엽니다. 자 이렇게 터미널 두 개를 열어서 파이썬 가상 환경을 세팅했던이 폴더로 갑니다. 저 같은 경우에는 C의 패스트 API 스타디 폴더고요. 어이 부분은 저희가 앞서 그 패스트 API 환경 설정할 때 말씀을 드렸죠. 자, 여기에 가상 환경이 설치된 곳으로 가서 가상 환경을 이렇게 활성화시키겠습니다. 자, 그러면 앞에 이렇게 가상 환경이라고 붙었고요. 유비콘으로 두 개 서브를 포트를 다르게 해서 띄워 보겠습니다. 여기에 있는 명령어를 복사해서 자 위에는 8,000번 밑에는 8,1번으로 띄우겠습니다.
자, 서버 띄울 때 여기 이름 이렇게 법업 서버로 해 주셔야 됩니다. 자, 서로 다른 서버로 해서 어플리케이션 두 개를 띄웠습니다. 자, 이제 브라우저를 열어서 각각 프론트 환경으로 접속해 보겠습니다. 자, 이렇게 크롬 브라우저를 가지고 이렇게 양쪽에 두 개 브라우저를 양쪽에 이렇게 나눴습니다. 자, 여기는 8,000번 보트고요. 8,000번에 스웨어 UI고 여기는 클라이언트 테스트 페이지인데요. 지금 안 나오네요. 네, 이제 나오네요. 어, URL이 제가 잘못했네요. 여기 보면 자, 8,번에 이게 섭섭으로 접근해야 되고요. 여기 왼쪽에 스웨거는 이렇게 독수로 접근해야 됩니다. 자, 밑에도 마찬가지고요. 자, 독수로 8,1번 독수로 오고 여기는 8,1번섭으로 접근하면 됩니다. 여기가. 자, 이렇게 해서 어, 여기 소외그 UI를 가지고 어, 발행을 해서 양쪽 다 잘 수신이 되는지 한번 보겠습니다. 위에는 8,번, 밑에는 8,1번에서 실행되는 클라이언트 페이지들입니다. 자, 퍼블리스 노티스가 발행하는 엔더인트죠. 자, 여기가 발행하는 엔드포인트입니다.
여기서 공지를 발행해 보겠습니다. 자, 저는 8,번이죠? 8,번에서 반응합니다. 그러면 이렇게 양쪽 다 잘 수신이 되는지 보시면 됩니다. 자, 잘 수순이 됐죠? 8,000번 뭐 자기 자신한테 이렇게 온 거죠? 그리고 8,1번에서도 8,번이 발행한 걸 즉시 받았습니다. 어, 이번에는 여기 8,1번에서 한번 8,1번. 자, 이렇게 해도 양쪽 다 와야 되겠죠? 실시간으로. 자, 발행. 자, 바로 왔죠? 한 번 더. 한 번 더. 계속. 자, 여기 1 11 1 11 1 여기는 2 2 할까요? 자, 자, 계속 나오죠. 2 111 2 자, 양쪽 다 어디에서 발행하든지 실시간으로 양쪽 다 수신할 수 있죠. 지금은 서버가 두 대밖에 없지만 서버가 뭐 수십대가 되든 몇백대가 되든 같은 채널을 구독하고 있으면 어느 한 곳에서만 발행하면 전체 앱에서 다 받아서 클렌트로 전송할 수 있는 거죠. 자, 직접 소스를 받아서 한번 테스트해 보세요. 자, 이렇게 해서 레디스의 팝섭 기능을 우리 백엔드 어플리케이션 즉 패스트 API로 구현한 백엔드 어플리케이션에서 어떻게 레지스의 팝섭을 구현하고 구독해서 처리하는지를 알아봤습니다.
어 다시 한번 더 말씀드리지만 현재 우리 실습 구조에서 클라이언트 수만큼 이렇게 팝섭 연결 객체가 생성되고 구독하는 건 어 실제로는 안티 패턴입니다. 저희 샘플에서는 클라이언트가 접속해서 바로 메시지를 받을 수 있는 그런 형태를 아주 심플하게 구현하기 위해서 이렇게 한 것이고요. 어 실제 실무에서는 여러 개 실제 그 사용자들은 굉장히 많을 수 있잖아요. 이런 사용자들이이 서버 A가 있고 서버 B가 있고 이럴 경우 이렇게 많이 붙을 수 있어요. 이런 사람이. 그리고 레디스가 이렇게 있고. 자,이 섭섭 관련된이 커넥션 객체는이 서비스가 시작할 때 이렇게 한 번만 사용해서 구독을 한 번만 해서 대기하고 있는 거예요. 그리고 이렇게 클라이언트가 만일 서버 센터 이벤트로 많이 이렇게 연결을 유지해야 된다면 그럴 때마다 우리 실섭처럼 이렇게 연결하는게 아니라 어 폼서 앞단에서 서버가 시작할 때 이미 한 번만 연결돼서 구독되기 중이고 클라이언트가 이렇게 들어오는 것들은 별도의 어떤 자료 구조에 뭐 Q 같은 자료 구조에 계속 담아뒀다가이 서버가 구독 채널을 통해서 메시지를 받으면 자기 메모리에 있는이 클라이언트들한테 다 전송하는 코드를 구현하는 것이 정석입니다.
입니다. 그래서 우리 코드에이 부분들은 패스트 API에서 레디스의 구독을 어떻게 처리하는지 그 메커니즘을 이해하는 수준으로만 활용하시면 됩니다. 실제 환경에서는 서버가 처음 시작할 때 한 번 구독 처리하고 서버가 종료할 때 구독을 해제하는 형태로 구현하시면 됩니다. 자, 오늘 강의 요약하겠습니다. 어, 브로드캐스팅.이 이 레디스의 법섭은 1대 N 통신을 지원합니다. 그래서 어 분사한 서버 환경에서 어떤 데이터 이벤트를 공유하는 가장 심플한 수단입니다. 자, 그리고 커넥션 분리 한 번 더 말씀드립니다. 어, 팝선만을 위한 전용 커넥션을 만들어서 사용하셔야 합니다. 그래야 어, 레지스의 다른 명령어들을 다른 연결 객체를 통해서 수행할 수 있습니다. 자, 그리고이 SS는 넘어가고요. 한번 읽어 보시고요. 자, 폼섭은 휘발성이라 그랬죠. 메시지를 보관하지 않으므로 어 현재 접속 중인 유저에게만 어떤 적각적인 알림을 줄 때 가장 빠르고 저렴하고요. 어 만일에이 반드시 나중에라도 처리돼야 되는 그런 아주 미션 크리티컬한 그런 업무 뭐 주문이나 결제 이벤트 처리 같은 그런 업무에서는이 팝섭을 사용하면 안 되고 어 레지스터 스트림이나 뭐 별도의 그 카프카 같은 MQ를 사용해야 됩니다.
자, 오늘 수가했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 YouTube 코딩하는기술사 (개발/IT)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기