[Notion] 언제 터질지 모르는 Notion 서비스 운영하면서 느낀점

Eunjun Jang·2020년 12월 12일
0

thumbnail

지난 글에서는 서비스를 시작하기 앞서 서비스에 필요한 요구사항들을 보고 그것을 구현하기 위한 여러가지 방법중 노션과 구글 앱스 스크립트, 파이썬을 선택했다. 그래서 잘 만들어서 학생들이 얼른 영상을 올려주기를 기다리고 있었다. 파이썬 스크립트를 실행할 서버는 Azure VM을 하나 만들어서 사용했다. 저걸 만들 당시에는 방학이라 편하게 하루종일 시간을 쓸 수 있었다. 하지만 10월달에 취업을 하고 11월달에 학생들이 본격적으로 영상을 올리기 시작했다.

구글폼에는 있지만 홈페이지에는 없는 것

회사에서 열심히 일하고 있는데 선생님에게 전화가 와서 학생 8명이 영상을 제출했는데 홈페이지에 올라가지 않았다고 이야기했다. 바로 Azure VM으로 접속하고자 했는데 왠걸 접속이 안되는 것이다... 뭔가 이상했다. 난 분명 서버를 계속 켜두고 지냈는데 왜 서버 접속이 안되는 걸까 싶었다. 구글 앱스 스크립트 요청에서 500 Internal server error가 계속 찍혀있었다. ssh접속이 안되니까 결국에는 Azure VM 인스턴스를 싹 제거하고 새로 만들었다. 그리고 필요한 환경을 다시 구축하고 플라스크 서버를 돌리고 설문지에 더미데이터를 넣고 정상 접수를 확인했다. 이미 접수된 8개 영상에 대해서는 수동으로 파이썬에 데이터를 넣어 업로드를 마쳤다.

이로써 이제 잘 고친줄 알았더니...

플라스크 서버 프로세스가 없어지는 현상

정확히 말해서는 영상 업로드가 안된다고 해서 들어가보니 실행시켜놓고 나온 플라스크 서버 파이썬 프로세스가 ps -ef 했을때 없는 것이다. 그냥 프로세스가 죽은 것일 거다. 이때 머리를 스쳐 지나간 것은 ssh 클라이언트에서 실행한 파이썬 프로그램이 ssh 연결 종료 했을 때 같이 사라지는가 이다. 예상은 정확하게 맞았고, 생각해보면 당연한거였다. 파이썬 인터프리터의 부모 프로세스인 ssh가 꺼졌는데 자식인 파이썬 프로세스가 없어지지 않을 리가 없다. 그래서 생각해보면 ssh를 종료하는 순간 플라스크 서버는 그냥 꺼지게 되는 것이었다. 이런 멍청한 짓을 했다..

해결하는 방법을 찾아봤는데 screen 을 사용하는게 가장 쉬워서 임시로 screen을 사용해 플라스크 서버를 켜고 나온 다음 다시 들어갔을때 정상적으로 돌아가고 있는 것을 확인했다.

구글 드라이브 트래픽 초과

내가 구상한 서비스 흐름에 의하면, 구글폼으로 접수받은 영상은 드라이브에 저장되고, 그 드라이브 주소를 POST에 담아서 플라스크 서버에 요청하고 요청을 받으면 해당 정보를 담아 백그라운드로 노션에 업로드 하는 스크립트를 실행한다. 노션에 업로드 하는 스크립트는 실행될때 CLI로 정보들을 받아서 업로드할 영상 ID를 URL에서 추출하고 drive.google.com/uc?id=... URL을 태워서 비디오 블럭에 url로 연결시켰다.

몇번 내가 테스트해봤을 때 전혀 문제가 없었다. 하지만 많은 사용자들이 홈페이지에 접속해 영상을 보기 시작하니 문제가 되었다. 그때 당시 홈페이지 메인에는 태그별로 갤러리뷰가 있어서 한 영상이 적어도 두번씩 노출되었고, 내 생각인데 Notion은 페이지를 리로딩할때마다 링크된 컨텐츠를 불러오는 것 같다. 그래서 불과 몇명만 동시 접속해도 몇개의 영상 컨텐츠의 구글 드라이브 URL 요청이 구글측에 막혀서 Sorry.. 라는 제목으로 너네 자동화된 쿼리가 너무 많아서 우리 사용자 보호하기 위해 너네 블락함 ㅅㄱ 라는 내용을 영어로 말한 html페이지가 보여지는 문제가 발생했다.

제일 먼저 생각난 해결방법은 링크로 영상을 걸지말고 영상을 다운받아서 embed하자는 방법이었다. 이게 유효할 것이라고 생각한 이유는 앞에서 말한 트래픽과 관련된 문제이다. 다운받아서 embed하는 방법은 업로드 할때 단 한번 google drive url에 GET요청을 하게 된다. 하지만 link로 영상을 걸어놓으면 노션 페이지를 들어갈때마다 url GET 요청을 하는 것 같다.

그래서 우선 백엔드 서버의 노션 업로드 스크립트를 수정했다. 구글드라이브 영상을 다운로드 한다음에 영상을 첨부하는 방법으로 전환했다. 영상 파일을 첨부하게 되면 이 영상은 노션의 AWS서버에 업로드 되어서 아무리 많이 요청해도 노션페이지에서 보는 것이기 때문에 트래픽 제한이 없어서 괜찮았다.

MOV파일을 윈도우에서 보기

이로써 열심히 안정적으로 영상들을 잘 업로드 하고 있을 줄 알았던 내 서비스는 다시 위기를 맞이하게 된다. 아이폰에서 촬영한 MOV 파일이 업로드 했을때 윈도우OS에서 보여지지 않는다는 문제였다. 이것은 순수 노션 문제이다. 왜냐하면 MOV파일을 재생하는 영상 플레이어에서 이를 지원하지 않거나 제대로 지원할 수 없기 때문이다. 노션측에 이걸 클레임 걸어서 해결하기엔 너무 오래걸리니까 그냥 바로 내가 할 수 있는 일들을 찾았다.

해결방법은 간단했다. 구글 드라이브에서 영상파일을 다운로드하고 이 파일이 MOV인지 MP4인지 확인해서 MP4이면 그대로 임베드, MOV면 MP4로 변환후 임베드 하는 방법이었다. 여기서 문제는 두가지.

  1. 영상포멧을 유추할 수 없다.

    구글 드라이브에서 영상을 다운받을 때 파일에 대한 정보 없이 파일을 받기 때문에 파일명을 알수도 없고 임의로 지정한 이름으로 받기 때문에 확장자를 통해서 영상 포멧을 알수도 없다. 따라서 파일을 직접 열어서 어떤 파일인지 분석하는 방법밖에 없다.

    이것을 해결하기 위해 나는 여러가지 구글링을 했고, 결국 답을 찾았다. Magic이라는 라이브러리를 사용하면 파일의 확장자를 몰라도 이 파일이 어떤 형식인지 알 수 있게 해준다. 이 라이브러리는 꽤나 옛날부터 있었고 파이썬 버전으로 바인딩 된 라이브러리를 찾을 수 있었다. 그래서 이 라이브러리를 사용해 내가 다운받은 영상파일이 mov인지를 체크할 수 있었다.

  2. 파이썬으로 영상 인코딩을 변경하는 방법

    MOV영상인지 확인했으니까 이제 이 영상을 MP4 형식으로 변환해주는 라이브러리를 찾아야 했다. 여러가지 라이브러리들이 많았다. 깃허브에 검색하니까 꽤 많은 라이브러리를 찾을 수 있었다. 하지만 생각보다 쉽게 쓸만한 라이브러리가 없었다. 굉장히 자세한 파라미터들을 담아야 했었다. 나는 그냥 mov가 재생안되니까 mp4로 바꾸는건데 무슨 코덱 라이브러리, 오디오 대역, 영상압축, 해상도 등등 정해야 하는게 너무 많았다. 그냥 쓸 수 있는 라이브러리를 찾아보다가 스택오버플로에서 moviepy라는 라이브러리를 알게되었고, 이 라이브러리는 내가 딱 원하는 심플함 그자체로, 함수호출 두번으로 컨버팅이 가능했다.

    하지만 문제점은 MOV에서 MP4로 변환할때 CPU와 RAM자원을 너무 많이 먹는다는 것이었다.

서버가 너무 느릴때는 돈이다

또 무난하게 서비스 하던 와중에 영상을 올린 친구로 부터 문자를 받게 되는데, 영상이 안올라간다는 것이다. 그래서 확인하려고 보니까 어느새 screen으로 띄운 플라스크서버가 죽어있었다. 로그를 확인할 수 없어서 screen으로 다시 플라스크를 띄우고 수동으로 업로드를 했는데, 원인이 보였다.

원인은 심플했다. moviepy로 mov파일을 mp4로 변환하는 도중에 RAM이 없어서 뻗는 문제였다. 이것은 내가 뭐 어떻게 할 수 없는 문제였다. 기존에 Azure VM은 아마 내 기억상 B1s였나 램이 1GB짜리 였던걸로 기억한다. 그래 부족할 수 있다는 생각을 하고 그냥 Azure VM 인스턴스 사양이 더 좋고 더 큰걸로 업그레이드 시켰다. 다행이도 Azure VM 사양 업그레이드는 버튼 두번 클릭으로 알아서 데이터 그대로 업그레이드 시켜줘서 좋았다. 사양을 변경한 이후, 업로드 속도가 기존보다 훨씬 좋아졌다.

또 다시 구글 드라이브에 막히다

그렇게 또 서비스가 잘 유지되다가 문제가 발생한다. 이놈의 문제가 너무 많이 발생한다. 이번 문제는 돈으로도 해결할 수 없는 구글드라이브 API 요청한도에 직면했다. 영상을 다운받으려면 구글드라이브 url을 GET 요청해서 영상을 다운받아야 하는데 요청 한도에 막혀서 다운받은 영상이 html포멧으로 인식되어 업로드가 제대로 안되는 문제였다.

우선 급하게 구멍난 곳을 납땜한다는 마음으로 파일 포멧이 html이면 구글 드라이브 raw url로 링크걸고 나중에 제한 풀리면 다시 업로드 해야지 하는 마음으로 그렇게 했다. 이 문제는 진짜 노답이었다.

그냥 속시원하게 처음부터 구글에서 정식으로 제공하는 API를 쓸껄 그랬다. 괜히 Auth와 여러가지 귀찮음 때문에 야매로 구현한 라이브러리를 쓰다가 이렇게 피를 많이 봤다.

역시 PM2.

Screen을 사용해 띄운 플라스크 서버는 오류로 죽었을때 무슨 로그를 남기는지 볼수가 없는 문제가 있었다. 그래서 이걸 어떻게 개선할까 고민했었다. 예전에 모두리스트 만들때 AWS에서 Nodejs로 백엔드 서버(Velopert님 튜토리얼 보고 조금 수정한) 만들었던 기억을 더듬어 그때 PM2라는 패키지를 사용해서 서버가 죽었을때 자동으로 재시작해주는 친구를 기억해냈다. 그 친구가 파이썬 스크립트도 돌릴 수 있는지 알아봤고 가능하다고 해서 바로 node와 npm을 설치하고 pm2를 깔아 플라스크 웹서버를 돌렸다. 너무 만족스러웠다. 에러로그랑 일반 로그가 분리되어서 보이고 서버가 죽어도 다시 시작되니까 너무 좋았다.

이렇게 다사다난한 서비스는 접수일이 종료되고 구글 입력 폼 북마크 블럭을 노션에서 없애버리고 Callout블럭을 통해 이쁘게 접수마감을 알렸다.

서비스를 끝마치고 되돌아보면서도 느낀점이 있다. 이것은 또 다음 글에서 나눌 예정이다.

profile
"Whether you eat or drink, or whatever you do, do all to the glory of God."

0개의 댓글