Skip to content
isdnetworks
Go back

동작을 바꾸지 않는 사전 배포

(수정됨)

상품 이미지를 읽는 방식을 바꿔야 했다. 지금은 channel_products 가 products.image_path 를 그대로 참조하는데 앞으로는 자식이 자기 image_path 를 갖고 없을 때만 부모 것을 쓰게 하려는 것이었다.

Table of contents

Open Table of contents

문제 — 같이 내보낼 때의 문제

grep -rn image_path 로 읽는 곳을 세니 여덟 군데였고 상세와 목록과 내보내기와 마켓 전송과 캐시 생성과 관리자 화면과 배치가 걸려 있었다. 쓰기 쪽도 자식 저장 시 자기 이미지를 만들도록 바꿔야 했다.

두 가지 방법이 있었는데 둘을 같은 배포에 넣는 것과 읽기를 먼저 내보내고 쓰기를 뒤에 내보내는 것이다. 뒤쪽을 골랐다. 이유는 읽기 여덟 곳 중 하나가 잘못되면 화면이 깨지고 쓰기가 잘못되면 자식 이미지가 안 생기는데 둘이 같이 나가면 문제가 생겼을 때 어느 쪽인지 알 수 없고 되돌리려 해도 통째로 되돌려야 해서다. 대신 배포가 두 번이 되고 그 사이 기간 동안 아무 동작도 안 바뀌는 코드가 운영에 있는 것을 감수했다.

해결 — 발동할 수 없는 조건

순서를 바꿔 읽기를 먼저 내보내되 그 코드가 절대 발동하지 않는 조건으로 넣었다. 읽기 로직을 productImage() 헬퍼 하나로 모으고 자기 것이 있으면 자기 것을 없으면 부모 것을 반환하게 했다.

지금은 자식에게 자기 이미지가 하나도 없으므로 첫 분기가 항상 거짓이고 모든 호출이 부모 것을 반환한다. 여덟 곳을 건드린 배포인데 동작이 하나도 안 바뀌는 상태가 된다.

검증 — 무동작의 증명

안 바뀔 것 같다는 판단으로는 부족해서 배포 전에 셋을 확인했다. channel_products 에서 image_path IS NOT NULL 이 0건인지를 실제로 셌는데 하나라도 있으면 그 상품만 동작이 바뀐다.

여덟 곳이 정말 다 productImage() 로 교체됐는지도 grep 으로 셌다. 기존 호출이 남아 있으면 그곳만 옛 경로를 타서 나중에 화면마다 다른 이미지가 나온다. 마지막으로 배포 전후에 상품 20건의 이미지 주소를 뽑아 대조했다. 전부 같았다.

조치 — 플래그 하나로 한 전환

읽기가 나간 뒤 쓰기를 별도로 배포하면서 CHILD_IMAGE_ENABLED 플래그를 달았고 .env 기본값은 false 였다. 배포해도 아무 일이 없다.

그다음 카나리 서버 web-01 한 대에서만 켰다. 그 순간부터 그 서버로 저장된 상품만 자기 이미지를 갖게 되고 그 상품에서만 읽기 쪽 첫 분기가 발동하므로 여덟 곳을 건드린 변경의 실질 위험이 카나리 한 대에 갇혔다.

주의 — 관측과 적용 조건

카나리에서 이틀 동안 셋을 봤다. 자식 이미지가 생성되는지를 건수로 세고 그 상품의 화면을 표본으로 확인했다. 마켓 전송은 로그와 상대 화면으로 확인했다.

셋 다 정상인 것을 보고 나머지 서버에 켜고 기존 상품에 대한 backfill:child-images 를 돌렸다. 이 방식은 준비 비용이 있다. 그래서 읽는 곳이 많고 읽기와 쓰기를 분리할 수 있으며 되돌리기가 비싼 경우에 쓴다. 새 경로가 기존 데이터에서도 발동하면 이 방법이 성립하지 않고 그때는 읽기 쪽에도 플래그가 필요해 분기가 두 겹이 된다.

정리


Share this post on:

Previous Post
하나에만 있던 게이트
Next Post
계측은 필요한 입도에서 한다