본문 바로가기

개발/개발공부 일지

[22.01.17 ~ 22.01.23] FCM 작업, 첫 유닛테스트 코드 작성, mongod.lock is not empty 에러

1. FCM  작업 

FCM(Firebase Cloud Messaging)은 클라이언트 앱에 메시지를 보내는 수단이다.

 

FCM을 클라이언트에 전송하는 방법은 3가지가 있는데,

 

  1. 단일 기기에 전송
  2. 기기 그룹에 전송
  3. 특정 주제(topic)을 구독한 기기에 전송

이다.

 

나의 경험을 바탕으로 3가지를 설명하자면,

 

1. 단일 기기에 전송

서버에서 특정 기기에 메시지를 전송하는 방법이다. Request Body의 to 값에 특정기기의 fcmToken 값을 넣으면 된다. 각 기기의 fcmToken값을 서버에서 관리하고 있어야 한다.

 

서버에서는 아래와 같이 HTTP요청만 보내주면 끝이다!

 

Request URL: 'https://fcm.googleapis.com/fcm/send'
Request Method: POST

<Request Headers>
Authorization: 'key=서버 키 값'

<Request Body>
{
    to: 특정기기의 fcmToken,
    data: {
      보내고자 하는 데이터 (필수아님)
      },
    notification: {
      title: 제목,
      body: 내용
      },
    sound: 값,
    priority: 값,
    ...
}

 

 

2. 기기 그룹에 전송

서버에서 기기그룹을 만들어 관리하고, 해당 기기그룹에만 메시지를 보낼 수 있는 방법이다. (공식문서: https://firebase.google.com/docs/cloud-messaging/android/device-group?hl=ko )

사실 이 방법은 사용해보지 않아 자세히 설명하진 못하겠다💦

 

3. 특정 주제(topic)을 구독한 기기에 전송

이 방법은 앱에서 특정 주제를 임의로 구독하여 알림을 받을 지 결정할 수 있다는 점에서 2번 방법과 차이가 있다. 앱에 알림을 보내야 하는지 서버에서 모르는 경우 사용하기 적절할 듯 하다. Request Body의 to 값이 '/topics/주제 이름' 이 된다는것 말고는 1번과 동일하게 보내면 된다.

각 기기의 fcmToken 값을 서버에서 관리하지 않아도 된다는 장점이 있다.

 

주의할 점은 Authorization값 입력 시 'key=서버 키 값' 이 통째로 value로 들어가야한다는 것이다!

 

firebase 콘솔의 서버 키 위치. 프로젝트 설정(톱니바퀴 아이콘) -> 클라우드 메시징 페이지에 있음.

 

서버에서 payload를 어떻게 구성해야할 지에 대한 내용은 공식문서 Firebase 클라우드 메시징 HTTP 프로토콜 (https://firebase.google.com/docs/cloud-messaging/http-server-ref?hl=ko)에 자세히 나와있다.

 

사실 FCM 메시지를 보내는것은 서버 보다는 앱에서 처리할 게 많고 내용이 복잡하다!

 

2. 첫 유닛테스트 코드 작성

위의 FCM코드 작업을 하며 (제대로된)첫 유닛 테스트코드를 만들어 붙였다!

 

처음 입사하여 사수가 테스트코드를 붙여보라는 과제를 주었었는데, 그때는 정말 유닛테스트라는게 왜 필요한건지 이해가 안되었다. 그때 내가만들고 있던 프로젝트는 도서관리 프로그램으로 정말 간단한 CRUD 밖에 없었기 때문에 테스트코드를 만드는 시간이 굉장히 비효율적으로 느껴졌다.

 

그런데 지금 유지보수중인 프로젝트는 복잡한 비즈니스 요구사항을 담아야 해서 유닛도 상당히 복잡하다. 그래서, 개발하면서 postman으로 해보는 테스트 보다는 제대로된 테스트코드를 만들어야 겠다는 생각이 자연스럽게, 자발적으로 들었다!

 

테스트코드를 만들어 돌리니, 마음이 편해지는 느낌이었다.

 

정말 이런 느낌

 

 

앞으로 코드를 작성할 때 postman으로 하나하나 테스트해보기 보다는 유닛테스트 코드를 만들어 테스트하는 쪽으로 하게될 것 같다!

 

3. mongod.lock is not empty 에러

컴퓨터에 문제가 생겨 강제종료를 하였는데 다음날 도커로 컨테이너들을 실행시키니 mongodb가 실행되지 않았다. (당황..)

 

문제의 mongodb 로그

 

mongoDB가 비정상적으로 종료되어 lock파일이 남아있기 때문에 생기는 에러이다.

 

해결방법

해결방법을 말하자면, repair 명령어로 mongodb를 수리(?) 해 주면 된다. 주의할 점은 비정상 종료 시 완전히 저장되지 않은 상태의 데이터가 날아갈 수도 있다는것...

 

다음 링크에 자세한 해결방법이 있다. (링크: https://github.com/docker-library/mongo/issues/62 )

 

docker-compose 로 mongoDB를 실행시키고 있는 경우 아래의 방법을 사용하면 된다.

 

 

db 에는 mongodb 컨테이너 이름을 적자.

 

 

MongoDB WiredTiger에 대하여

그리고 위의 에러로그를 읽다가 WiredTiger 라는 뜬금없는 단어가 나와 무엇인지 궁금해 검색해 보았는데

굉장한 블로그를 발견했다. 상당히 넓은 분야를 공부하고, 정리해서 포스팅을 하고 계셨다.

 

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ijoos&logNo=221324560518

 

WiredTiger (MongoDB Storage) - MongoDB DBA Exam

이번에는 MongoDB의 Storage에 대해서 알아보고자 한다. (주로 WiredTiger 에 대해서 배워보도록 하...

blog.naver.com

 

 

위의 글에 따르면 mongodb는 WiredTiger, MMAPv1, In-Memory 의 3가지 타입의 Storage Engine을 지원하고, WiredTiger는 MongoDB 3.2부터 default로 지정되는 Storage Engine이라고 한다. 

 

그리고, WiredTiger는 document-level의 concurrency를 사용하여 복수의 사용자가 같은 시간대에 같은 document에 접근할 수 없다는 내용도 있었다. 글로만 배웠던 데이터 무결성을 MongoDB에서 WiredTiger라는 엔진이 어떻게 보장하는지 실제로 보게되니 매우 신기했다.

 

위 블로그의 글쓴이가 MongoDB DBA 시험에 나오는 내용을 정리한 듯 한데, 나중에 DBA 시험도 공부해보고 싶다.