서버를 EC2로 옮길 결심을 하면서 백엔드 프레임웍도 바꾸기로 했다. Nginx에서 시작하여 deno + oak 로 동작하던 것을 Nginx를 빼고 bun(node.js) + nestjs ( fastify + gzip + ssl + file logging) 로 변경하는데 3주 정도 걸렸다. 다행히 typescript 그대로 사용하고 mongodb 다루는 것도 라이브러리 인터페이스가 동일해서 비지니스 로직이 크게 변경되는 것은 없었다.
클라우드 전환은 EC2 1개 만들고 고정IP하나 할당한 것이 전부다. EC2에 도커와 bun 설치하고 도커로 mongo db 설치한 후 소스코드 복사후 서버를 돌려봤다. 보름이 지났는데 아직까진 큰 문제는 없다. 사실 EC2로 옮기는 것은 1년전에 GCP에서 오라클 클라우드로 이전한 경험이 있어서 어렵지는 않았다. 오히려 로드 밸런서와 Nginx을 빼버려서 서버 구조가 간단해졌다.
AWS를 사용하나 GCP를 사용하나 어차피 vm만 사용하는 거라 크게 다른 것은 없는 것 같다. vm의 성능도 1명이 테스트 하는 것이라 체감상으로는 차이가 없다. 다만 비용적으로는 AWS가 조금 더 싸거나 비슷할 것이라 생각했는데 비용이 생각보다 많이 나왔다. 비용분석을 해보니 공인 IP 비용이 vm 사용료와 비슷하게 과금됬다. AWS가 최근에 공인 IP 사용을 유료화했기 때문이다. 대응책으로 EC2에 IPv6을 적용하는 것은 어렵지 않아 보인다. 다만 IPv6 서버에 접속하려면 단말도 IPv6가 되어야하는데 이게 쉽지 않다. 휴대폰이 Wifi가 아닌 3G 이상 일때는 문제가 없는 것 같은데 Wifi인 경우 공유기에서 IPv6를 지원하는 경우가 별로 없어 보인다. 테스트 단계라서 확실하지는 않다. 그냥 애저나 OCP로 가볼까 싶기도하다. 어차피 나만 쓰는 건데..
EC2를 장기 계약하는 방법으로도 vm 사용료를 줄일 수 있을듯 하다. 어차피 최소 사양이라 계산해 보니 1년에 2만원 조금 더 아낄 수 있는 수준이다. 아니면 EC2를 하루에 몇 시간만 돌리는 방법도 있다. 하지만 이것은 혼자 사용할 때나 가능한 옵션이고 혼자여도 매우 불편하기는 하다. 공인IP비용과 EBS는 장기 계약의 대상은 아닌듯.. 결국에는 빨리 서비스를 런칭해서 서버비 정도는 벌어보는 게 오늘의 결론인가.. 년 15만원 정도.. 결국은 모든 혁신과 추진력과 실행력은 돈이었다는..ㅎㅎ 돈이 많이 안 들어갈 때는 느긋했는데 1인 독푸딩 단계에서 이미 비용이 많아지는 느낌이라 고민이다.
=== 6/6일 추가 ===
급하게 애저로 vm을 변경해봤다. 애저로 변경시 장점: 12개월 무료 플랜 사용 가능.., 장기 예약 결재하면 비용 절감이 다른 곳에 비해 크다고 한다. 우분투 22.04 로 vm 생성 CentOS로 하려니 뭐가 잘 안 된다. CentOS버전은 왜 이리 많은건지 선택장애.. 오히려 우분투로 해도 크게 어려운 점은 없었다. 도커 설치만 조금 다를 뿐 나머지는 대동소이하다. 애저는 기본 로그인 아이디를 설정할 수 있는데 그냥 AWS와 동일하게 ec2-user로 했다. 대신 호스트 이름에 Azure_Backend1 으로 해서 명령줄에서 구분은 되게 했다.
도커 설치
bun 설치
도커로 mongodb 설치
도커로 SSL 인증서 설치
서버 코드 복사후 서버 구동
재부팅시 서버 자동 실행 설정 (기본 설정의 스크립트 위치는 /etc/rc.local 이다)
Cron으로 db 백업 설정
AWS의 VM 중지
AWS의 공인 IP 연결 끊고 반납
AWS의 EBS는 당분간 유지(나중에 혹시 몰라) 이것도 조금이기는 하지만 비용이 나가니 애저 서버가 문제가 없다면 VM과 함께 삭제할 예정이다.
내가 느끼기에는 vm은 모든 클라우드가 비슷하다. AWS가 1등이기는 하지만 다른 클라우드에 비해 비싼 것 같다. 다만 규모가 커졌을때 스케일 업이나 기타 여러가지 다른 서비스 연동시 차이가 있겠지만 현재 단계에서는 그것까지 고려하지 않아도 된다. 그리고 애저 리전을 한국으로 했더니 응답이 2~3배 빨라졌다.
애저 시도하기전에 OCI 계정을 살려보려 했으나 실패했다. OCI는 로그인 할때, 오라클 계정과 사용자 이름 그리고 무슨 테넌시 인가하는 것을 입력하게 되어 있는데 왜 이렇게 만들었을까? 다 비슷해서 헤깔리고 오래되서 기억나지 않는다. 찾기를 하면 그런 email이 없다고 하고 다시 가입하려고 하면 중복된 email이라고 한다. 점유율이 2%인 이유가 있는것 같다.
=== 6/25일 추가 ===
애저 vm서버가 응답없음 상태로 종종 빠지는 문제가 있는데 해결을 못하고 있다. 자주 겪었다. 처음에는 원인을 몰랐는데 느낌적으로 정기적인 vm 업데이트 과정중에 발생하는 것 같다. 문제가 생기면 서비스 뿐만 아니라 ssh 접속이 안 되기 때문에 강제로 vm을 종료후 다시 시작해야한다. 강제 종료도 15분 이상 걸릴때가 있다. vm포탈에서 보면 가상 머신 agent도 응답없음 상태라고 나온다.
과도하게 Disk Read와 CPU 사용률을 보이는데 왜 그런지 몰랐는데.
우현히 Agent가 뭔가 업데이트를 하고 있는 순간을 찍었다.
그 후에 이렇게 다시 vm 응답없음이 되었다. 30gb SSD인데 654gb 디스크를 읽는게 정상인가?
????
일단 업데이트 정책을 변경해본다. 이미지 기본값으로 변경했다.
==== 7/1 추가 ====
주의깊게 여러 테스트를 해 본 결과 bun을 사용시 vm이 network 응답없음이 되는 경우가 있었다. 이때까지 총 4번 정도 발생을 했고 애저 콘솔에서 bun install이나 bun run 을 실행했을 뿐인데, 동작중인 앱서비스가 서비스 불가가 되었고 ssh도 접속이 안 되었고, 역시 애저 에이전트도 응답없음이 되었다. 이게 버그라면 굉장히 치명적인 버그인데... 맥니미에서는 발생하지 않았고 생각해보니 AWS에서도 비슷한 일로 vm을 강제 종료했던 경험이 있는데 이것이 원인이 아닌가 의심이 든다. 아직 해결책은 모르겠다. 구글링해도 bun 실행이 hang이 걸린다는 것은 많으나 network를 망까뜨린다는 건 나오지 않는다.
일단 대응은 vm이 죽으면 안 되기 때문에 bun대신에 node js로 서버를 돌리기로 했다. bun에서 그냥 지원되던 top-level await가 node js에서는 안 되기 때문에 조금 수정할 필요가 있었다. 하지만 Fastify를 사용하고 있어서 난해한 에러 1개가 있었는데 어찌어찌 해결했다. @fastify/compress 와 fastify 패키지를 같이 설치를 하면 app.registrer(compression) 부분에서 문법 오류가 나온다. @fastify/compress 대신에 fastify-compress를 설치할 수 있는데 이건 deprecated되었고 버전도 맞지 않아서 역시 실행되지 않는다.
'FastifyCompress' 형식의 인수는 'FastifyPluginCallback<FastifyCompressOptions> | FastifyPluginAsync<FastifyCompressOptions> | Promise<...> | Promise<...>' 형식의 매개 변수에 할당될 수 없습니다.\n 'FastifyCompress' 형식은 'FastifyPluginCallback<FastifyCompressOptions>' 형식에 할당할 수 없습니다.\n 'instance' 및 'instance' 매개 변수의 형식이 호환되지 않습니다.\n
https://github.com/nestjs/nest/issues/11265#issuecomment-2119100260 이쪽 링크를 참조해서 해결했다. (node_modules/@nestjs/platform-fastify/package.json 의 fastify 버전과 달라서 생긴 문제였고 맞추니 해결되었다. ) fastify 는 FastifyRequest와 FastifyReply를 참조해야해서 필요했다. 속도도 빠르고 여러가지 자체적으로 지원하는게 많아서 왠만하면 bun을 계속 사용하고 싶기는 하지만 node js로 돌려보고 동일한 문제가 다시 생기는지 확인해볼 필요가 있다. mongodb upload하는 스크립트는 mongo_upload.ts는 cron서비스로 하루에 1번 실행되는데 이건 ts-node로 실행되도록 수정했다. 다행히 오류 없이 한 번에 실행되었다. bun사용과 비교했을때 npm install이 가장 시간이 오래걸린다.
==== 7/6일 추가 ====
NODE js로 런타임을 변경후에 5일 간 서버가 죽지 않았다. 오늘 아침에 서버가 응답이 없었는데 그건 1달이 지나서 VMStoppedToWarnSubscription 가 발생했다. 계속하려면 업그레이드하라는 뜻이다. 업그레이드하면 12개월 무료 플랜은 계속 사용할 수 있고 일부는 유료로 계속 사용해야 한다. 보니깐 VM은 무료로 일정기간 무료로 사용할 수 있는 듯 하나 스토리지와 네트웍은 무료가 아니라서 조금 돈이 들것 같다.
==== 9/1 일 추가 ====
애저 vm의 업데이트 정책을 원래대로 되돌려서 서버가 다운되는지 다시 테스트해 보았는데 한 달 넘게 문제가 없었다. 그 동안 업데이트 중에 리부팅이 한 번 되었는데 자동 시작 스크립트에 의해서 서버는 재시작되었고 29일 이상 문제없이 동작했다. 따라서 vm 응답없음의 원인은 bun js 런타임이라고 추정한다.