골프 코스트 지역의 기상 예보 사이트에 wp-discourse 플러그인을 사용하려고 계획하고 있습니다. 이 사이트는 평소 하루 약 10,000~20,000페이지의 조회수를 기록하지만, 심한 기상 이벤트가 발생하면 하루 150만~200만 페이지 조회수에 약 50만~70만 명의 방문자가 몰리기도 합니다. 사이트와 호스팅 전략은 여러 번의 심한 기상 이벤트를 거치며 검증되었기 때문에, 정밀한 설계와 Cloudflare의 많은 도움 덕분에 압력 하에서도 훌륭하게 작동합니다.
사이트 사용자는 네이티브 워드프레스 댓글을 통한 저마찰(저장벽) 댓글 작성 경험에 익숙하므로, 일부 적응 과정(예: “…에서 토론을 계속하세요” 링크를 클릭하는 것에 익숙해지는 것 등)이 필요할 것입니다. 이는 사용자 응대 담당 직원이 관리할 준비가 되어 있습니다.
그러나 그들이 용납하지 못할 것은 댓글 게시와 일일 워드프레스 게시물 페이지에 댓글이 표시되는 사이의 가변적인 10분 지연입니다. 네이티브 WP 댓글이 게시 직후 즉시 표시되는 것과 유사하게, 새 댓글(설정된 한도 내에서)이 게시된 직후 홈페이지에 즉시 표시되기를 원합니다.
nginx의 fastcgi 캐싱, 워드프레스, 또는 브라우저 캐싱이 게시 후 새로고침 시 새 댓글이 표시되는 것을 방해하지 않도록 내장 옵션을 가지고 씨름한 끝에, 워드프레스 측에서 새로고침 시 새 게시된 댓글이 표시되도록 이 문제를 완화하기 위해 다음 두 개의 mu-plugin을 추가했습니다:
이로써 제 문제는 해결되었습니다: 워드프레스 생성의 Discourse 스레드에 새 게시물이 올라오면 이제 워드프레스 게시물 아래에 새로고침 시 즉시 표시됩니다.
하지만 여기서 제 역량 한계에 도달한 것 같습니다 — 이렇게 함으로써 무엇을 깨뜨리거나, 엉망으로 만들거나, 훼손하고 있을까요?
일일 기상 예보 페이지(임베디드 Discourse 댓글 포함)를 확인하는 방문자들이 댓글 엔드포인트를 마구 때려내어 웹호스트에 추가 부하를 주는 것에 대해서는 특별히 신경 쓰지 않습니다. 이는 돈을 들여 해결할 수 있는 문제입니다. 제 1차 요구사항은 20,000명 이상의 사용자가 댓글을 게시했는데 왜 홈페이지에 즉시 표시되지 않느냐고 이메일을 보내는 것을 피하는 것입니다.
이것이 올바른 접근 방식인가요? 제가 하는 일이 현명한가요? 예상하지 못한 추가적인 보안이나 성능 문제를 발생시키나요? 기본적으로, 이렇게 해서 일을 망치고 있는 건가요?
문제는 이러한 성공 메시지가 있음에도 불구하고, 기존 방문자(적어도 저의 경우, Mac에서 Firefox/Safari/Chrome, Win10 PC에서 Firefox/Chrome/Edge, iOS에서 Safari를 여러 번 테스트했는데)들이 cache-control 헤더가 0이 아닌 값으로 설정된 캐시된 /wp-json/wp-discourse/v1/discourse-comments 엔드포인트를 계속 받아보고 있다는 점입니다. Chrome에서 Ctrl+Shift+F5(또는 다른 브라우저의 동등한 단축키)를 눌러 로컬 캐시를 우회하고 새로고침을 강제하면, 모든 것이 정상 작동하며 새 게시물이 표시됩니다.
mu-plugins가 설치된 상태에서는 해당 엔드포인트의 cache-control이 no-store no-cache 등으로 설정되어 있고, 문제 행동이 나타나지 않습니다—단순히 WP 게시물을 방문하거나 일반 새로고침 버튼으로 새로고침해도 새로운 임베드된 댓글이 표시됩니다.
상세한 웹훅 로그를 켜고 테스트 게시물을 작성했는데, 새 게시물을 만들 때 모든 것이 정상으로 보입니다:
모든 것이 작동하는 것처럼 보이지만, 여전히 원래 문제 행동이 왜 나타났는지, 아니면 제 쪽에서 간과한 어떤 문제에서 비롯된 것인지 정확히 이해하지는 못합니다. (매우 가능성이 높습니다!)
아, 죄송합니다. 제가 그 부분을 실수한 것 같다는 말씀에 동의합니다. 어제는 긴 하루였고, 말씀드린 것처럼 제 능력의 한계 근처에 있는 상태입니다. 분명히 _무언가_는 하고 있었지만, 이제 제가 보고 있는 “수정된” 행동이 단순히 새로운 방식으로 깨져 있는 것인지 궁금해집니다. (이제 “transient killer” 플러그인을 올바른 인수를 사용하도록 업데이트했습니다. 감사합니다!)
Cache Comment HTML 설정을 활성화하거나 비활성화한 경우 모두 시도해 보았는데, 문제 동작에 아무런 영향을 미치지 않는 것 같습니다. 현재는 비활성화 활성화 상태입니다(죄송합니다. 제가 잘못 말씀했네요. 계속 확인해 보고 있는 중이라 현재는 활성화되어 있습니다). 문제 해결에 도움이 된다면 설정을 어떻게든 변경할 수 있습니다.
nginx + php-fpm 8.3 환경에서 자체 호스팅된 WP를 사용 중입니다. 동적 콘텐츠에는 nginx fast-cgi 캐싱을, 객체 캐싱에는 Redis를 사용하며(객체 캐시 드롭인이 활성화됨) 다른 레이어(CDN, CF, nginx fast-cgi 캐시 외에 서버 내 Varnish 또는 기타 로컬 캐시)는 없습니다. nginx fast cgi 캐시를 강제로 비우는 작업(rm -rf /etc/nginx/cache/* 실행)은 문제의 동작에 영향을 미치지 않습니다 — 캐시 디렉토리를 삭제하고 nginx와 php-fpm을 모두 재시작해도 여전히 오래된 결과가 제공됩니다.
실제로 현재 Ajax 댓글 로딩이 활성화되어 있지만, 이를 끄고(혹시 모를 경우를 대비해 nginx 캐시 비우기 및 nginx와 php-fpm 재시작 포함)도 문제의 동작에는 변화가 없었습니다. 브라우저가 여전히 오래된 댓글을 가져오기 때문입니다.
옵션을 전환하고 transient-killer를 제거했습니다. 문제의 동작에는 변화가 없습니다.
이 플러그인이 적용하는 효과는 캐시 시간을 지정하는 헤더 대신 no-cache cache-control 헤더를 제공하는 것으로 보입니다. 이 플러그인이 없으면 브라우저는 wp-json/wp-discourse/v1/discourse-comments 엔드포인트의 오래된 캐시 버전을 디스크 캐시에서 제공하려는 경향이 매우 강합니다. 언급했듯이, no-cache 새로고침을 강제하려면 shift-ctrl-f5(또는 동등한 단축키)를 사용해야 합니다.
문제 동작은 영구적인 서버 측 캐시가 아니라 브라우저 측에 있는 것 같습니다. 제가 접근할 수 있는 모든 OS의 모든 브라우저에서 동일한 현상이 일어나고 있기 때문입니다.
해결책을 찾지 못하고 헤매게 된다면, 그리고 원하신다면, 문제를 해결하기 위해 내일이나 그 다음 날 WP 블로그, 디스커스, 그리고/또는 기반 호스트에 대한 임시 로컬 접근 권한을 부여할 수 있습니다. 물론 무상 노동을 받으려는 것은 절대 아닙니다. 실제로 시간이 소요된다면 서비스 비용을 기꺼이 지불하겠습니다.
참고로, 워드프레스를 호스팅하는 서버와 디스코드를 실행하는 서버 모두 AWS의 Ubuntu 24.04 AMI를 실행하는 t3a.large EC2 인스턴스입니다. 설치된 소프트웨어는 최소한으로 유지되고 있습니다(웹 호스트에는 nginx + php8 + fpm + redis, 디스커스 호스트에는 git + docker + discourse 이상). 이는 제 개인 블로그이며, OP에서 언급된 훨씬 더 큰 규모의 WP 사이트에서 프로덕션으로 배포하기 전에 여기서 댓글 통합을 테스트하고 있습니다. (저는 그 사이트도 관리하고 있으며 유사한 기술 스택을 사용하지만, Cloudflare가 프론트엔드에 위치해 있습니다. 그 부분은 때가 되면 다룰 것입니다!)
한 달여 뒤에야 답글을 올려서 마무리합니다. 여전히 전체 프로덕션 배포 시 이상한 현상들이 발생하고 있습니다 (prod 사이트, 디스커스 임베드가 포함된 예시 프로덕션 사이트 게시물, 실제 디스커스 포럼) 하지만 모두 관리 가능한 수준입니다. 남은 지연/지체 문제는 워드프레스 + 디스커스 + 클라우드플레어로 이루어진 복잡한 레이어 케이크와, 실제 폭풍으로 인한 트래픽 폭증 시 모든 시스템이 운영될 수 있도록 유지하기 위한 제 공격적인 캐싱 전략 탓으로 돌리겠습니다.
다시 한번 이 글을 올려 죄송합니다. 다만, 문제의 원인을 찾았으니 후속 보고를 하고 싶었습니다. 그리고 그 원인은 역시 제 실수였습니다.
간단히 말씀드리면, 저는 /etc/nginx/snippets/ 아래에 일반적인 PHP location 블록 세부 정보를 스니펫으로 관리하고 있습니다. 이렇게 하면 여러 vhost 파일에서 이를 포함할 때 매번 중복해서 작성할 필요가 없기 때문입니다. 이 스니펫을 확인한 지 아주 오래(아마도 수년)되었는데, 예상대로 add_header Cache-Control "public, max-age=7200";라는 불필요한 설정이 남아 있었습니다. 이 설정은 해당 location 블록을 통해 나가는 모든 요청에 적용되고 있었습니다.
그래서 해당 설정을 제거하고 모든 캐시 계층을 비웠더니, 정말로 문제 증상이 사라졌습니다.
@angus 님, 제 실수로 인한 또 다른 Discourse 문제였음에도 불구하고 시간을 내어 도움을 주셔서 다시 한번 감사드립니다.