오늘은 다중 서버 환경에 대비한 SSE 통신 관리를 진행하였다!
SSE 통신을 위해서는 SSE Emitter 객체를 만들고, 이 Emitter 객체를 어플리케이션에서 저장하고, 관리해야 한다.
그런데, 이때 Emitter 객체는 하나의 어플리케이션의 메모리에만 저장하게 된다.
우리 서비스를 배포할 때 사용자가 많아질 경우, EC2 서버를 하나 더 생성하여 ALB를 통하여 유저의 트래픽을 관리하려고 한다.
그래서 사용자가 서버1과의 통신으로 SSE Emitter 객체를 생성하였지만, 사용자에게 가야하는 알림이 서버2에서 만들어지는 상황이 생길 수 있다.
이렇게 되면 서버2는 사용자와 연결된 SSE에 대한 정보를 가지고 있지 않으니 알림을 보내줄 수 없게 된다.
그래서 이런 상황에 대비하기 위해서 레디스의 Pub/Sub을 도입해보았다.
레디스 Pub/Sub은 특정한 주제(topic)에 대하여 해당 topic을 구독한 모두에게 메시지를 발행하는 통신 방법을 제공한다.
유저1과 서버1이 SSE로 연결되면, 서버1은 채널명 channel:userId:1으로 구독을 진행한다.
이후 서버2에서 유저1에게 보낼 알림 이벤트가 발생하면, 레디스 Publisher는 유저1의 채널(channel:userId:1)로 메시지를 발행한다.
그러면 레디스는 해당 채널을 구독한 Subcriber에게 메시지를 전달하고, 이 Subscriber를 가지고 있는 서버1에서 유저의 emitter를 찾아 알림 데이터를 전송한다.
이렇게 구현할 경우, 서버 몇 대를 사용하든, 어느 서버에서 알림이 생성되든 상관없이 사용자에게 알림을 전송할 수 있게 된다.
하지만, 언제나 그렇듯 레디스를 사용할 때는 레디스 장애 시 대처 방법에 대해서도 생각해보아야 하는데,
아직까지는 그렇다 할만한 대책이 떠오르지 않는다.
이 부분에 대해서는 조금 더 고민해보면서 찾아보아야 할 것 같다.
우리 팀이 작성한 코드는 깃허브를 통해 업로드해두었다.
GitHub 보러가기
확실히 하나의 서비스를 만들어 운영한다는 것은 굉장히 까다로운 것 같다.
하나하나 고려해야 할 것들도 많고, 생각하면 생각할수록 더 많은 경우의 수들이 떠오른다.
그래도 이런 상황들을 하나하나 생각해보면서 해결책을 찾아가는 과정들이 재미있다.
언젠가는 실제 서비스가 어떻게 구성되고, 돌아가게 되는지도 체험해보고 싶다.