image 61

일본 서버 이전, 꿈은 컸지만… 현실은 예상 밖 삽질의 연속

일본 서버 이전, 꿈은 컸지만… 현실은 예상 밖 삽질의 연속

클라우드 서버 이전. 야심 찬 목표를 품고 시작했지만, 현실은 녹록지 않았습니다. 마치 드넓은 태평양을 항해하는 배처럼, 기대와 설렘으로 가득 찼지만, 막상 뚜껑을 열어보니 예상치 못한 암초들이 곳곳에 도사리고 있었죠. “이번 일본 서버 이전만 성공하면…” 이라는 달콤한 상상은 시작에 불과했습니다.

저희 팀은 오래된 온프레미스 서버를 클라우드로 이전하기로 결정했습니다. 이유는 명확했습니다. 늘어나는 트래픽 감당 불가, 잦은 장애, 그리고 무엇보다 비효율적인 유지보수 비용 때문이었죠. 클라우드로 이전하면 확장성, 안정성, 비용 효율성, 세 마리 토끼를 잡을 수 있다는 장밋빛 전망이 저희를 사로잡았습니다.

하지만 현실은 달랐습니다. 서버 이전 프로젝트는 시작부터 삐걱거렸습니다. 가장 큰 문제는 바로 ‘언어’였습니다. 일본 서버였기 때문에, 모든 문서와 설정이 일본어로 되어 있었죠. 개발팀은 일본어 능통자가 부족했고, 번역기를 돌려가며 겨우 내용을 파악해야 했습니다. 마치 고대 상형문자를 해독하는 기분이랄까요?

게다가 기존 서버 환경에 대한 완벽한 이해 없이 무턱대고 클라우드로 옮기려다 보니, 호환성 문제, 데이터 손실 위험 등 예상치 못한 난관들이 속속들이 나타났습니다. 마치 엉성하게 쌓아 올린 탑이 무너지는 것처럼, 하나씩 문제들이 터져 나오기 시작했죠.

이때부터 저희는 밤샘 작업, 끝없는 회의, 그리고 좌절과 번뇌의 시간을 보내야 했습니다. ‘잘 될 거야’라는 긍정 회로는 이미 과부하 상태였고, 현실은 냉혹했습니다. 그래도 포기할 수는 없었습니다. 이미 배는 태평양 한가운데 떠 있었고, 돌아갈 수도 없었으니까요.

이제부터 제가 겪었던 황당한 실수 3가지에 대해 자세히 이야기해 볼까 합니다. 이 실수들은 값비싼 수업료를 치르고 얻은 교훈과도 같습니다. 부디 이 글을 읽는 분들은 저희와 같은 실수를 반복하지 않기를 바랍니다. 다음 섹션에서는 일본 서버 이전 후 겪었던 첫 번째 황당한 실수에 대해 이야기해보겠습니다.

첫 번째 함정: 언어 설정 미스로 데이터베이스가 혼또니 고멘나사이?

일본 서버 이전 후 겪었던 황당한 실수 3가지 (반면교사)

첫 번째 함정: 언어 설정 미스로 데이터베이스가 혼또니 고멘나사이?

분명 UTF-8로 설정했는데 왜 한글이 깨져 보이는 걸까요? 일본 서버로 이전하면서 가장 먼저 겪었던 황당한 경험은 바로 데이터베이스 언어 설정 문제였습니다. 에이, 설마 UTF-8 설정 안 했을 리가. 저도 처음엔 그렇게 생각했습니다. 하지만 현실은 냉혹했죠. 서버 이전 후 데이터베이스에 접속해보니, 멀쩡하던 한글 데이터들이 외계어처럼 뭉개져 있는 것을 보고 아찔했습니다. 마치 혼또니 고멘나사이!라고 외치는 듯한 모습이었죠.

삽질의 시작: 분명 나는 UTF-8로…

문제 해결을 위해 가장 먼저 확인한 것은 당연히 데이터베이스 연결 설정이었습니다. 꼼꼼하게 확인했지만, 역시나 UTF-8로 설정되어 있었습니다. 이럴 리가 없는데…라는 생각과 함께 구글링을 시작했습니다. 다양한 해결 방법들이 쏟아져 나왔지만, 대부분 비슷한 내용이었습니다. 연결 문자 집합 설정, 테이블 문자 집합 설정 등등. 제시된 방법들을 하나씩 적용해 봤지만, 결과는 달라지지 않았습니다. 마치 미로 속에 갇힌 기분이었죠.

원인은 간단했지만, 해결 과정은 험난했다

결국 문제의 원인은 예상치 못한 곳에 있었습니다. 바로 MySQL 설정 파일 (my.cnf) 내의 기본 문자 집합 설정이 UTF-8이 아닌 다른 값으로 설정되어 있었던 것입니다. 데이터베이스 연결 설정은 UTF-8로 되어 있었지만, 서버 자체의 기본 설정이 다르니 데이터가 제대로 처리되지 못했던 것이죠. my.cnf 파일을 열어 character-set-servercollation-server 설정을 UTF-8로 변경하고 MySQL 서버를 재시작하니, 드디어 깨졌던 한글 데이터들이 정상적으로 표시되기 시작했습니다.

경험에서 얻은 교훈: 기본을 간과하지 말자

이 경험을 통해 얻은 교훈은 기본을 간과하지 말자는 것이었습니다. 데이터베이스 연결 설정만 확인하고 서버 자체의 기본 설정은 확인하지 않았던 것이 실수였죠. 이후로는 서버 이전이나 데이터베이스 관련 해외서버 작업을 할 때, 연결 설정뿐만 아니라 서버의 기본 설정까지 꼼꼼하게 확인하는 습관을 가지게 되었습니다. 마치 집을 지을 때 기초 공사를 튼튼히 하는 것처럼, 서버 설정 역시 기본부터 확실하게 다져야 한다는 것을 깨달았습니다.

이처럼 언어 설정은 데이터베이스 운영의 기본 중의 기본입니다. 만약 저처럼 언어 설정 문제로 곤란을 겪고 있다면, 데이터베이스 연결 설정뿐만 아니라 서버의 기본 설정까지 꼼꼼하게 확인해 보시길 바랍니다.

다음 섹션에서는 서버 이전 후 겪었던 또 다른 황당한 실수, 바로 방화벽 설정에 대한 이야기를 풀어보겠습니다. 예상치 못한 곳에서 터진 방화벽 문제 때문에 얼마나 당황했었는지, 그리고 https://ko.wikipedia.org/wiki/해외서버 어떻게 해결했는지 자세하게 알려드릴게요.

두 번째 난관: 잘 되겠지 안일함이 부른 CORS 에러 폭탄

두 번째 난관: 잘 되겠지 안일함이 부른 CORS 에러 폭탄

일본 서버 이전, 생각보다 만만치 않았습니다. 데이터베이스 설정, 네트워크 점검 등등, 눈코 뜰 새 없이 바빴죠. 이제 다 끝났겠지? 안도의 한숨을 내쉬는 순간, 예상치 못한 복병이 튀어나왔습니다. 개발 서버에서는 그토록 멀쩡하던 API들이 운영 환경에서 CORS 에러를 뿜어대기 시작한 겁니다! 마치 폭탄이라도 터진 것처럼 여기저기서 붉은색 에러 메시지가 쏟아져 나왔죠.

처음엔 뭐지, 또 뭐가 잘못된 거지? 싶었습니다. 로그를 뒤져보고, 설정 파일을 샅샅이 훑어봤지만, 딱히 눈에 띄는 문제는 없었습니다. 그러다 문득, Access-Control-Allow-Origin 헤더가 눈에 들어왔습니다. 아뿔싸, CORS 설정! 개발 서버에서는 대충 넘어갔던 부분이, 운영 환경이라는 엄격한 심판대 위에서 여지없이 드러난 겁니다.

CORS(Cross-Origin Resource Sharing)는 웹 브라우저의 보안 정책 때문에 발생하는 문제입니다. 쉽게 말해, 웹 페이지가 다른 도메인의 리소스를 요청할 때, 브라우저는 보안상의 이유로 기본적으로 이를 막습니다. Access-Control-Allow-Origin 헤더는 바로 이 제한을 풀어주는 역할을 합니다. 이 헤더에 허용된 도메인 정보가 없으면, 브라우저는 해당 요청을 거부하고 CORS 에러를 발생시키는 것이죠.

저는 즉시 Nginx 설정 파일을 열어 Access-Control-Allow-Origin 헤더를 추가하기 시작했습니다. 처음에는 특정 도메인만 허용하는 방식으로 설정했지만, 생각보다 다양한 도메인에서 API 요청이 들어오는 것을 확인하고는, 결국 와일드카드(*)를 사용하여 모든 도메인을 허용하는 방식으로 변경했습니다. (물론, 보안적인 측면에서는 권장되는 방식은 아닙니다. 상황에 따라 적절한 설정을 해야 합니다.)

location /api/ {
  add_header Access-Control-Allow-Origin *;
  add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS;
  add_header Access-Control-Allow-Headers DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range;
  add_header Access-Control-Expose-Headers Content-Length,Content-Range;
  if ($request_method = OPTIONS) {
    add_header Content-Type text/plain; charset=utf-8;
    add_header Content-Length 0;
    return 204;
  }
}

Nginx 설정을 변경하고 재시작하자, 거짓말처럼 CORS 에러가 사라졌습니다. 하지만 이 과정에서 꽤나 많은 시간을 허비했습니다. 잘 되겠지라는 안일한 생각으로 CORS 설정을 간과했던 대가였죠. 이후로는 개발 초기 단계부터 CORS 설정을 꼼꼼하게 확인하고, 운영 환경에 배포하기 전에 반드시 테스트하는 습관을 들이게 되었습니다. CORS, 이제는 뗄레야 뗄 수 없는 존재가 되었네요.

하지만 서버 이전 과정은 여기서 끝이 아니었습니다. CORS 에러를 해결하고 안심하는 것도 잠시, 이번에는 예상치 못한 데이터베이스 관련 문제가 발생했습니다. 다음 섹션에서는 데이터베이스 연결 오류를 해결하기 위해 제가 어떤 삽질을 했는지 자세히 이야기해 보겠습니다.

세 번째 실수: 백업은 필수 망각이 초래한 데이터 복구 대작전

세 번째 실수: 백업은 필수 망각이 초래한 데이터 복구 대작전

앞서 서버 이전 과정에서 DNS 설정 오류와 방화벽 설정을 제대로 확인하지 않아 겪었던 곤욕을 말씀드렸습니다. 하지만, 진짜 큰 일은 바로 세 번째 실수, 백업에서 터졌습니다. 아, 생각만 해도 등골이 서늘해지네요.

백업, 백날 말만 하면 뭐하나… 실천이 중요하지

사실 백업의 중요성을 모르는 사람은 없을 겁니다. 저 역시 마찬가지였죠. 아, 백업해야 하는데…라는 생각은 늘 머릿속에 있었지만, 이상하게도 다음 주에, 이번 달 안에라는 말로 계속 미루게 되더라고요. 마치 숙제처럼 느껴졌다고 해야 할까요? 그러던 어느 날, 예기치 못한 서버 오류가 발생했고, 그 결과는 참담했습니다. 일부 데이터베이스 파일이 손상되어 버린 겁니다.

순간 머릿속이 하얘졌습니다. 망했다…라는 생각밖에 들지 않더군요. 그동안 쌓아온 소중한 데이터들이 한순간에 날아갈 위기에 처한 겁니다. 그제야 백업이라는 단어가 뇌리에 강렬하게 박히면서 후회가 밀려왔습니다. 왜 그렇게 미뤘을까, 왜 좀 더 서둘러 백업 시스템을 구축하지 않았을까…

새벽을 밝힌 데이터 복구 혈투

다행히 완전한 손실은 막을 수 있었습니다. 부분적으로 남아있는 백업 파일들과 로그 기록을 토대로 새벽까지 데이터를 복구하는 작업을 진행했거든요. 밤새도록 터미널 창을 들여다보며, 명령어 하나하나에 집중했던 기억이 아직도 생생합니다. 정말이지, 그날만큼 백업의 소중함을 뼈저리게 느낀 적은 없었습니다.

데이터 복구 과정은 그야말로 대작전이었습니다. 손상된 데이터베이스를 복구하기 위해 온갖 방법을 동원했고, 혹시라도 데이터가 유실될까 봐 얼마나 가슴을 졸였는지 모릅니다. 가까스로 대부분의 데이터를 복구하는 데 성공했지만, 일부 데이터는 결국 복구하지 못했습니다. 작은 실수로 인해 큰 손실을 겪은 셈이죠.

백업 시스템 구축, 그리고 다짐

이 사건을 계기로 저는 즉시 자동 백업 시스템을 구축했습니다. 매일 새벽 3시에 전체 데이터베이스를 백업하고, 중요한 파일들은 실시간으로 클라우드에 백업하도록 설정했습니다. 또한, 주기적으로 백업 데이터를 복구하는 테스트를 진행하여 시스템의 안정성을 확보했습니다. 이제는 백업이 단순한 숙제가 아니라, 생명줄과 같은 존재가 되었습니다.

교훈: 백업은 선택이 아닌 필수

일본 서버 이전 후 겪었던 세 가지 황당한 실수를 통해 얻은 교훈은 명확합니다. 첫째, DNS 설정과 방화벽 설정은 서버 이전 전에 반드시 꼼꼼하게 확인해야 합니다. 둘째, 예상치 못한 오류에 대비하여 서버 이전 과정은 단계별로 진행하고, 각 단계마다 테스트를 거쳐야 합니다. 셋째, 그리고 가장 중요한 것, 백업은 선택이 아닌 필수입니다.

서버 운영은 마치 항해와 같습니다. 예측 불가능한 상황이 언제든지 발생할 수 있습니다. 따라서, 철저한 준비와 대비만이 안전한 항해를 보장할 수 있습니다. 부디 저의 경험이 다른 분들에게 반면교사가 되어, 안전하고 안정적인 서버 운영에 도움이 되기를 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다