-
앱 심사로 인한 서버 버전 관리 문제(feat , 무중단 배포)Project/NYAM 2023. 1. 9. 18:28
무중단 배포를 위한 첫 걸음
현재 팀에서는 대학생들이 사용하는 "앱"과 매장의 사장님들 혹은 팀의 운영팀이 매장을 등록하는 "웹" 두가지의 서비스를 운영 중입니다.
서비스 중인 모바일앱과 클라이언트 웹은 단일 서버 어플리케이션에서 API 를 사용합니다.
인프라는 다음과 같이 구성이 되어 있습니다.
- 1개의 EC2 에 2개의 백엔드 어플리케이션 (개발용 Dev서버, 운영 서버), Nginx 서버
- 2개의 DB Server(Dev 용, Release 용 MongoDB)
- 1개의 EC2 에 2개의 프론트 어플리케이션 (개발용 Web서버, 운영 서버)
- AWS S3 이미지 데이터용
Nginx 로 리버시 프록시을 구성하여 url 의 따라 web,mobile 운영 및 개발 서버로 요청을 받을 수 있게 구성하였습니다.
-----
이러한 열악한 (?) 상황에서 앱 심사를 하기 위하여 , 모바일 기능 변경사항을 위해 서버를 업데이트해야 합니다.
운영중인 서버를 앱 심사를 위하여 업데이트를 하게 되면 , 기존의 사용중인 앱 에서 에러가 발생할 수 있는 구조라는 것을 알게 되었습니다.
예)
1. GET Store 라는 API 가 운영 중 Apple Good이라는 단어를 Response 한다. (DB 에 Apple 이라는 칼럼이 있다.)
2. 새로운 모바일 기능에서 운영 심사를 위해 GET Store 라는 API 가 Banana Bad 라는 단어를 Response 해야한다.(DB 에 Banana 라는 칼럼이 이전과 다르게 있어야함)
-> 단일 서버 및 운영 DB로 구성이 되어 있는 상황에서 하나의 WAS 에서 같은 url 로 서로 다른 Response 를 반환을 해야하는 상황이 되었죠.
(항상 생기는 문제는 아닌것이 더 무섭네요)
당시 생각을 해본 해결 방식: 실재 운영중인 서버 에 추가로 심사 기간 동안 운영될 서버를 올린다.
개발에 사용할 서버까지 생각을 하면 총 4개가 AWS ec2 인스턴스에 올라가는 상황입니다.
-> 추가 적인 EC2 를 구성하는데는 심사 기간동안 심사에 사용될 트래픽이 많지가 않아 비용이 낭비가 있는 상황입니다.
해결책 : AWS EC2 의 앱 심사 기간, 심사 종료후에 이용될 앱과 통신할 추가 적인 서버, 추가적인 디비를 올립니다.
+ ssl 인증서를 발급한 추가 서브 도메인을 등록합니다.
시나리오
1. 앱 버전 v1.1.0 을 현제 서비스 중입니다.
( 서버도 앱 버전에 맞는 코드를 가집니다. - https api1.example.com 이 loacl 포트 3000 번으로 redirect 중)
2. 앱 과 서버 모두 개발이 완료가 되면 ,
3002 번 포트로 서버를 올립니다.
https 로 통신하는 api2.example.com는 을 local 포트 3002 번으로 연결 합니다.
앱의 url 은 api2.example.com으로 수정후 심사를 올립니다.
3.기존의 서비스 운영중인 데이터 베이스1에서 데이터를 덤프 후 api2 에 연결될 데이터베이스2에 넣고 추가적인 수정을 해줍니다.
앱을 심사 받습니다.
3. 앱 심사가 끝나면 3000 번 포트를 종료합니다.
4. 심사가 끝나면 앱 팀과 합의 한 업로드 날 전 후로 다시한번 데이터베이스2를 업데이트 합니다.
(앱을 심사받기전에 앱이 통과가 된다면 원하는 날에 스토어에 올리도록 설정을 할 수 있습니다.)
5. 앱스토어,플레이 스토어에서 업데이트를 한 유저는 api2 에 연결된 서버를 이용합니다.
기존 v1.1유저는 버전체크api를 통해 받은 업데이트가 필요하다라는 메시지를 받습니다.
6. 이후의 버전 업데이트는 2번상황에서 api1.example.com과 데이터베이스1 을 이용하여 준비를 합니다.
결론 :
- 추가적인 서버와 DB를 운용합니다.
- version check api 의 response 값을 추가하여 강제 업데이트 여부를 알려줍니다.
- 심사기간에는 두개의 릴리스 서버를 운영하여 v1.1 유저와, 업데이트 될 v1.2 를 지원 합니다.
- 심사 종료후에는 다시 하나의 서버로만 운영을 하며 서버의 전환을 Nginx 를 사용하여 무중단 배포를 진행합니다.
단점 : 무료 DB가 아니면 추가적인 비용이 발생합니다
: 몽고 디비는 추가적인 무료 DB 를 운영 가능합니다. 즉 저희 팀에는 이상이 없습니다.
위 방식이 나온 배경,
개발 서버, stage 서버 , dev server 를 운영하는 회사가 많다라는 사실을 듣고 구상했습니다.
추가적인 필요한 작업: Nginx 을 이용한 자동화
---NGINX---
erver { if ($host = api1.example.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = api2.example.com) { return 301 https://$host$request_uri; } if ($host = example.com) { return 301 https://$host$request_uri; } if ($host = cms.example.com) { return 301 https://$host$request_uri; } listen 80 ; listen [::]:80 ; server_name api1.example.com example.com cms.example.com api2.example.com; return 404; } #for Dev server{ listen 81; server_name api.example.com; location / { proxy_pass http://127.0.0.1:3003; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; } } #for Release server { # SSL configuration # # listen 443 ssl server_name api1.example.com cms.example.com api2.example.com; set $port 3000; if ($host = cms.example.com) { set $port 3001; } if ($host = api1.example.com) { set $port 3000; } if ($host = api2.example.com) { set $port 3002; } location / { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; ..(생략) }
작업 끝나고 찾아보니 카나리 배포 방식과 유사해보입니다.
------------------------------------------------------------------------------------------------
2025년에 이글을 다시 보니 다음과 같은 생각이 들었습니다.
당연하게 각 목적에 맞게 서버 인스턴스를 분리하고 , 내부망에 Was,Web 서버를 , 외부망에 nginx 를 서버를 구성.
-> 리버스 프록시 서버 1개, 개발 web,was 서버 각 1개, 운영 web, was 서버 각 2개 = (1 + 2 + 4) = 7개 로 운영.
이중화로 구성하여 운영 하면 안정적이 겠지만,, 가난한 대학생 스타트업 팀에서는 불가능했을 것 같네요.
당시 매출이 없는 상황에서 서비스를 개발 및 운영을 하는데 매달 나오는 인프라 비용이 5만원 내로 해결해야 했습니다.
당시 인프라 구성을 변경 못하니 API설계 및 DB 설계를 조금 더 잘하면 좋지 않았을까 합니다.
API 해더 또는 host 가 아니 리소스 경로에 버전 정보를 넣고 운영을 하는 것을 당시에 생각을 못했던 것 같네요.(경험이 없으니,,)
새로운 API에서 제공 하거나 접근하는 리소스가(DB) , 기존 운영과 달라야하니 서버를 새로 올려야 문제를 해결 할 수 있다는 생각에 잡혀있었던 것 같습니다.
DB -> WAS -> WEB, Mobile 각각에서 사용하는 데이터가 DB 중심적으로 설계가 되어 있어,, 3 tier 라도 의존성이 강했습니다.
또한, 당시 프론트 웹과 모바일 부문의 경험이 부족하여 리소스 경로에 버저닝을 넣는 것이 관리가 어려웠을 수 있지만, 돌아보니 하나의 클라이언트에서 서로 다른 두가지 버전의 api 를 호출이 가능한 개발이 가능 하지 않았을까 생각이 듭니다.
-> 경험과 아는게 많아야 더 좋은 설계가 가능하다 라는 경험을 하네요 ㅎ
'Project > NYAM' 카테고리의 다른 글
AWS s3 객체 url 접근 (0) 2023.02.03 Package.json 스크립트 작성 (0) 2023.01.19 [Errno 13] Permission denied: '/var/log/letsencrypt/.certbot.lock' (0) 2023.01.09 NestJs Swagger Header 추가 (0) 2023.01.02 서버를 날렸습니다! (1) 2022.12.10