💋 인트로
이 포스팅은 우아한테크코스5기 깃짱이 코치 토미의 강의를 듣고 작성했습니다.
💋 서비스 장애
서비스의 장애는 언제 발생할까?
새로운 기능을 만들어서 코드에 변경사항이 있을 때
서비스 장애를 만들지 않으려면 어떻게 하면 될까?
서비스 장애에 좋은 방법은, 새로운 기능을 만들지 않는 것이다.
하지만 돈을 받는데, 그렇게 할 수는 없다.
이 포스팅은 아래 질문들에 대한 조금의 대답이 될 수 있다.
- 어떻게 배포를 조금 더 안정적으로 할 수 있을까?
- 문제가 발생하더라도 어떻게 더 일찍 복구할 수 있을까?
💋 무중단 배포의 필요성
✔ 서버 점검은 줄어든걸까?
요즘은 큰 서비스를 사용하면서 위와 같은 페이지를 볼수 없다.
서버 정기점검이 줄어든걸까? 정기점검을 하지 않는걸까?
✔ 맨땅에 배포 과정에서 겪는 문제점
스프링부트를 사용해서 애플리케이션을 개발중이라고 생각해보자.
변화된 코드를 배포하기 위해서 기존에 돌아가던 톰캣 서버를 잠시 내리고,
새로운 코드로 다시 빌드한 뒤에 다시 톰캣 서버를 띄우는 것이 일반적이다.
하지만 이렇게 되면, 다시 빌드 후 서버를 띄울 동안 서비스를 이용할 수 없게 된다.
서비스 초기에 배포할 때마다 서비스가 중단되는 경험을 한다면, 사용자가 더이상 서비스를 이용하지 않게 될 수도 있다.
우리나라에 한정된 서비스라면, 새벽에 하는 것도 방법이다.
실제로도 인프라와 관련된 큰 변화는 새벽 4시에 하기도 한다.
배포하기까지 2분 정도 걸린다고 생각해보자!
이렇게 잠깐 중단되는건 괜찮지 않을까..?
사용자는 2분의 서비스 중단을 참아줄 수 있을까?
한 시간에 6만 건의 주문이 발생한다고 생각해보자. 그러면 1분에 1000건이고, 2분이면 2000건이다. 보통 주문할 때 2만원 정도 주문한다고 하면 4000만원 정도를 잃게 된다.
내가 개발자라면 4천마넌짜리 배포를 과연 할 수 있을까?
아무튼 무중단 배포가 필요하다는 말에는 충분히 설득력을 얻을 수 있을 것 같다.
💋 무중단 배포의 방법
구체적인 방법으로는 정말 여러 가지가 있다.
이 포스팅에서 구체적인 방법을 다루지는 않는다.
그치만 기본적인 개념은 아래와 같다.
먼저 처음에는 잘 돌아가고 있는 서버가 있다.
변경사항이 생긴 코드를 빌드하는 서버를 별도로 둔다. 그리고 이때 요청이 서버로 들어오기 전에 한 번 요청을 걸러주는 역할을 하는 서버가 필요하다. (웹 서버가 필요할 것이다!)
새로운 버전의 코드가 배포 완료되어 서버에 띄워졌다면, 이전 버전의 코드를 사용하는 서버는 동작하지 않도록 요청이 흘러들어가는 것을 끊어버린다.
물론 새로운 코드를 빌드하고 배포하는 서버가 꼭 분리되어야 하는 것은 아니다. 포트 포워딩만 제대로 해줄 수 있다면, 8080에 띄워두었다가 8081로 옮기고, 하면서 돌아가면서 사용해도 된다.
💋 무중단 배포 시 고려사항
✔ 프론트엔드와 백엔드 중 어떤 코드를 먼저 배포해야 할까?
프론트엔드 코드를 배포하면, 사용자가 보는 화면이 바뀌게 된다.
위 예시의 경우에 프론트엔드를 배포하면 사용자가 보는 화면에 닉네임 input이 추가되고, 백엔드를 배포하면 API에 닉네임 필드가 추가된다.
어떤 코드부터 배포해야 할까?
동시에 하면 좋겠지만,
프론트와 백엔드를 동시에 배포하는 것은 불가능하다.
위의 예시에서처럼 중간에 화면이 완전히 바뀌게 되었다면, 백엔드는 기존 화면을 보고 있는 사용자도 있다고 생각하고 개발해야 한다. 백엔드 개발자는 항상 이전 코드의 하위 호환성을 고려해야 한다는 뜻이다.
백엔드 개발자는 사용자가 보는 화면이 업데이트된 새로운 버전이라는 가정을 하지 않고 개발하는 것이 굉장히 중요하다.
생각보다, 고객들은 한 페이지를 띄워놓고 한참 시간이 흐른 뒤에 요청을 보내기도 한다. 카드 결제를 하고 나서 승인 버튼을 누르기까지의 시간을 측정해 보았을 때, 24시간이 지났을 때 누른 고객도 존재한다고 한다. 따라서 배포한지 24시간이 지났더라도 고객이 새로운 화면을 보고 있을 것이라는 제한을 두면 안된다.
위의 방법을 해결하는 하나의 방법으로는 백엔드를 먼저 닉네임을 필수값이 아니도록 배포하고, 이후에 프론트엔드에서 닉네임을 폼에 추가해 배포하고, 이후에 백엔드의 닉네임 값을 필수값으로 설정하는 방법이 있을 것이다.
보통 신규 칼럼이 추가되면 nullable로 추가하는 경우가 많다고 한다. 데이터의 성격에 따라서 시스템에서 마이그레이션이 가능하면 진행하고, 모든 데이터가 존재하는지 확인한 후에 not null로 변경하는 것이 안전하다.
그렇다면 영원히 하위호환을 고려해야 할까?
언제 백엔드가 변화된 로직을 완전히 적용할 지에 대해서는, 고객이 한 페이지에 머무는 시간을 측정해서 근거로 활용할 수 있다.
예를 들어 90%의 고객이 2일 내에 모두 새로고침을 통해서 새로운 화면을 본다고 모니터링이 된다면, “우리는 이틀 뒤에 전환한다”와 같은 정책을 정할 수도 있다.
✔ Schema, 인프라 작업은 언제, 어떻게 해야할까?
스키마 작업은 대부분 안전하지 않다.
어떤 스키마 작업의 경우에는 lock이 걸려서, 고객들이 데이터 조회를 못하거나 성능이 떨어질 수 있다.
인프라 작업 역시 마찬가지다.
인프라 변경 및 스키마 변경 작업은 고객이 서비스를 사용하지 않는 시간에 하는 경우가 많다.
배포를 하면서 문제가 생겼을 때, 코드의 문제인지 스키마의 문제인지 인프라의 문제인지 파악하기가 굉장히 어렵다.
따라서 운영에서는 ddl update 또는 flyway enabled true 조건을 잘 사용하지 않는다.
운영환경에서는 alter 권한이 없는 계정을 사용해야만 한다.
이렇게 하지 않으면, 배포하는 과정, 개발자들의 실수로 장애가 발생할 수 있다.
따라서 계정을 분리하고 권한을 나눠서 사용하는 것이 좋다.
💋 참고자료
'DevOps' 카테고리의 다른 글
[HTTPS] 무료 SSL 인증서 letsencrypt 명령어로 간단하게 발급받자! (0) | 2024.11.06 |
---|---|
[Infrastructure] 재배포 및 배포 롤백: 서비스 장애 발생 시 피해를 최소화하기 위한 롤백의 중요성 (2) | 2023.08.26 |
[Infrastructure] SPOF(Single Point of Failure)란? (4) | 2023.08.25 |