이번글은 저희의 home-delivery서비스는 유저 주문이 수락할경우, 주문취소, 라이더가 배달완료, 라이더가 음식픽업 시 알림이 가도록하기위한 알림 서비스를 구현하면서 경험을 작성하였습니다.
FCM이란?
Firebase 클라우드 메시징(FCM)은 메시지를 안정적으로 무료 전송할 수 있는 크로스 플랫폼 메시징 솔루션(교차 플랫폼)입니다.
FCM의 주요 기능으로는 알림 메시지 또는 데이터 메시지 전송, 다양한 메시지 타겟팅, 클라이언트 앱에서 메시지 전송 이있습니다. 이 중 저희가 필요한 부분은 알림 메시지였습니다.
FCM의 장점
1) FCM은 교차 플랫폼 메시지 솔루션이기 때문에 FCM을 이용해서 개발을 진행하면, 플랫폼에 종속되지 않고 Push 메시지를 전송할 수 있습니다. -> Web, Android, iOS 환경별로 개발할 필요가없습니다.
2) FCM에서 제공하는 여러 기능들도 함께 사용 가능합니다. ( GUI로 통계수치 등 )
3) 기능 구축에 시간과 비용이 줄어듭니다.
메시지 전송 구현 로직
1. 사용자의 토큰을 조회합니다.
2. FCM서버에 전송할 알림 메시지를 생성합니다.
3. FCM서버로 메시지를 전송하여 푸시알림을 전달합니다.
메시지 전송 구조도
결과
문제상황
제가 직접 간단하게 웹으로 알림메시지 전송이 되는지 확인하기위해 프론트를 구현하여 실험해봤습니다.
실험해봤을때는 메시지전송만 테스트해봤습니다. 알림서비스가 다른 로직과 결합될때를 생각해보았습니다.
알림 서비스는 알림 메시지를 FCM서버에 요청하고 FCM서버로 응답이 존재합니다.
1. 서버에서 외부FCM서버에 요청을보내고
2. FCM서버에서 성공여부 응답을 서버로 보내줍니다.
-> FCM서버로의 응답으로는 잘 보내졌는지 혹은 토큰이 유효하지않다는 응답이 존재합니다.
즉 2번과정에서 응답을 받을때 까지 스레드는 I/O Blocking 상황에 놓이게 됩니다.
메시지 전송로직이 주로 다른 로직과 함께 결합되어 사용되는데 이런경우 다른로직까지 성능을 떨어뜨리며
만약 점심, 저녁 피크타임이라면 알림으로 인해 성능에 부정적인 영향을 미칠것이라고 생각됬습니다.
해결 방법
해결방법은 비동기 처리를 생각했습니다.
메인스레드에서 알림서비스 로직에는 새로운 스레드를 생성해 처리하는 방법입니다.
이렇게된다면 응답을 기다리지않고 로직을 처리가 가능하기때문입니다.
이와같이 스프링에서 지원해주는 @Async를 사용해 메시지 알림 로직에서 발생하는 성능 저하를 방지했습니다.
개선결과
5번이상의 테스트를 진행하였습니다. 이로인한 결과는 위의 속도와 같습니다.
3,010ms -> 735ms (309%)로 성능을 개선되었습니다.
느낀점
알림서비스를 처음 구현해봤습니다.
알림서비스는 매우 간단할줄 알았으나 당근마켓 구조도를 보면서 서버가 더 커진다면 알림서비스에도 많이 복잡하고 고려할게 많다고 느꼈습니다. 푸시알림이 상당히 서비스에서도 중요하다고 생각되는 부분을 직접해보니 뿌듯했습니다.
FCM응답이 네트워크적으로도 거리가 멀기때문에 이로인한 영향도있다고 생각합니다. FCM서버가 어디에 존재하는지는 모르지만 사용지역에 가깝다면 더 빨라질거라 생각됩니다.
Reference
'Delivery' 카테고리의 다른 글
캐시 적용으로 읽기 성능 향상 (0) | 2022.09.08 |
---|---|
레디스 테스트코드 문제점 - TestContainer도입 (0) | 2022.08.19 |
Redis 장바구니 - 2 (Redis pipelining) (0) | 2022.08.18 |
Redis를 이용한 장바구니 - 1 (0) | 2022.08.15 |
리펙토링 디비조회 (0) | 2022.08.09 |