Skip to content
isdnetworks
Go back

주소가 가리키는 것이 달라졌다

서버를 두 대로 늘리면서 앞에 분산기를 뒀다. 그 뒤로 이상한 일이 몇 가지 생겼다.

Table of contents

Open Table of contents

주소의 뜻이 바뀌었다

전에는 도메인 하나가 서버 한 대였는데 이제는 두 대 중 하나가 됐다. 이 차이가 여러 곳에서 드러났다.

file_get_contents('http://shop.example.com/admin/cache/clear');

캐시를 지우는 코드인데 분산기가 아무 대에나 보내니 한 대만 지워진다. 다른 대는 옛 캐시를 계속 쓴다. 코드는 한 줄도 안 바뀌었는데 뜻이 바뀐 것이다.

자기 자신을 부르는 코드를 찾았다

같은 성질을 가진 자리를 전부 찾아야 했다.

$ grep -rn "shop.example.com" --include=*.php application/ | grep -v "base_url"

grep -rn 에서 넷이 나왔다. 캐시 지우기와 설정 다시 읽기와 파일 목록 새로 만들기와 상태 확인인데 넷 다 한 대에서만 일어나면 안 되는 것이었다.

각 대를 IP 로 직접 부르게 고쳤다. 하나가 실패하면 log_message 에 남게 했고 대 목록은 config->item('nodes') 로 뺐다. 코드에 두면 서버를 늘릴 때 잊는다.

file_get_contents$ctx 를 준 것은 기본 default_socket_timeout 이 60초라 한 대가 안 뜨면 전체가 그만큼 늘어지기 때문이다.

$nodes = $this->config->item('nodes');
foreach ($nodes as $ip) {
    $r = file_get_contents("http://$ip/admin/cache/clear", false, $ctx);
    log_message('info', "cache clear $ip: " . ($r === false ? 'FAIL' : 'OK'));
}

대마다 갖는 것과 공유하는 것

부르는 코드를 고치는 것보다 나은 방법이 있었다. 캐시를 대마다 갖지 않으면 지울 것도 하나다. 파일 캐시를 memcached 로 옮기니 지우는 것도 한 번이 됐다.

전부 옮기지는 못했다. APC 같은 코드 캐시는 그 서버 프로세스 안에 있으니 옮길 수 있는 것이 아니다. 그런 것은 배포할 때 각 대에서 처리하게 했다. 대마다 갖는 것과 공유하는 것을 갈라 정하고 나니 여러 대를 도는 코드가 줄었다.

올린 파일도 같은 문제였다. 관리자가 이미지를 올리면 move_uploaded_file 이 그 대의 디스크에만 쓰고 볼 때 다른 대로 가면 없다. 절반의 확률로 안 보인다. 업로드 폴더를 NFS 로 두 대가 같은 자리를 보게 했다. 그 저장소가 죽으면 둘 다 안 되는 것은 받아들여야 했는데 대신 파일이 한 벌만 있으니 백업도 한 번이면 됐다.

로그도 나뉘어 있어서 조사할 때 둘 다 봐야 했다. 한 자리로 모으는 것은 나중에 만들었고 그 전에는 ssh 로 두 대에 같은 grep 을 돌리는 스크립트를 두고 썼다. 로그 줄에 gethostname 을 넣은 것이 도움이 됐다. 모아 놓고 봐도 어디 것인지 갈린다.

확인 방법도 바뀌었다

고쳤다는 것을 확인하는 방법도 달라졌다. 전에는 주소를 한 번 열어 보면 됐는데 이제는 두 대에 다 반영됐는지 봐야 한다.

$ for h in 10.0.0.10 10.0.0.11; do
    echo -n "$h "; curl -s "http://$h/health" | grep -o '"rev":"[^"]*"'
  done

각 대의 IP 로 직접 curl 해서 rev 를 비교하는 것이다. 한 번 열어 보고 됐다고 하면 절반만 확인한 것이다. 실제로 한 대만 배포된 채로 며칠 간 적이 있었다. 분산기가 두 대에 나눠 보내니 어떤 사람은 새 판을 보고 어떤 사람은 옛 판을 봤다.

정리


Share this post on:

Previous Post
주문번호를 맞힐 수 있었다
Next Post
고쳤는데 다른 파일이 이기고 있었다