서버를 업그레이드하지 않고 관리 플러그인에서 오래된/거짓 RabbitMQ 연결 개체의 확산을 방지하려면 어떻게 해야 합니까?

서버를 업그레이드하지 않고 관리 플러그인에서 오래된/거짓 RabbitMQ 연결 개체의 확산을 방지하려면 어떻게 해야 합니까?

문맥:

우리는 중간 규모(수백 대에서 수천 대의 서버) 데이터 센터 전반의 메시징을 위해 RabbitMQ 2.8.4 HA 클러스터를 사용합니다. 메시징 기능은 우리 앱에 매우 중요합니다.

AMQP/RabbitMQ 작업에는 C 클라이언트 API를 사용하고 RabbitMQ 관리 플러그인에는 HTTP API를 사용하여 대기열 상태를 주기적으로 모니터링하고 크기/처리량 등에 따라 경고를 보냅니다.

클라이언트에서 메시징 서버로 허용되는 유일한 포트/연결은 AMQP 포트와 관리 API용 HTTP에 있습니다.

가까운 미래에 경영진은 메시징 클러스터의 가동 중지 시간(앱의 특정 요청 부분에 대한 가동 중지 시간으로 해석됨)을 용납할 수 없다고 결정했습니다. 몇 달 안에 가능하겠지만 그때까지는 영업 중심의 문제로 인해 메시징 시스템을 유지 관리할 수 없습니다. 안타깝지만 우리(인프라/개발 담당자)는 그러한 호출을 할 수 없습니다.

문제:

한동안 우리는 논의된 문제로 인해 피해를 입었습니다.이 SO 질문. 연결 급증 후 또는 새 클라이언트가 AMQP 시스템을 매우 자주 연결하고 사용하는 오랜 기간 후에 RabbitMQ 관리 API는 더 이상 존재하지 않는 "실행 중"으로 나열되는 수십만 개의 연결을 표시합니다. netstatlsof기타 진단을 통해 이러한 연결에 해당하는 소켓이 클라이언트에서 열려 있지 않음이 입증되었습니다. 관리 API가 어떤 이유로든 항목을 정리할 수 없습니다. rabbitmqctl list_connections때로는 존재하지 않는 연결 중 일부가 여전히 열려 있는 것으로 표시되지만 항상 관리 API보다 훨씬 적은 수로 표시되며 "부실" 감지가 API보다 더 나은 것처럼 보이며 결국 목록에서 잘못된 연결을 제거합니다.

웹 UI를 통해 이러한 "거짓" 연결 중 하나를 삭제하려고 시도하면 페이지는 "삭제"를 눌러도 응답하지 않으며 연결은 목록에 유지됩니다. JSON API에서 DELETE를 전송하여 삭제하려고 하면 연결이 유효하지 않아 삭제할 수 없음을 나타내는 500 서버 오류가 발생합니다(정확히 위의 연결된 SO 질문에 설명된 대로).

존재하지 않는 연결 개체가 오랫동안 축적되면 특별한 순서 없이 세 가지 나쁜 일이 발생합니다.

  • RabbitMQ 서버에는 대규모 메모리 급증이 있습니다(이는 갑자기 발생합니다. 이는 관리 API의 느린 연결 증가와 일치하지 않지만 메모리 소비는 시간이 지남에 따라 천천히 증가합니다). 이로 인해 충돌이 발생하는 경우가 많습니다.
  • 관리 API가 요청에 대한 응답을 중지합니다(API 클라이언트에서 시간 초과됨).
  • RabbitMQ 서버 자체는 HTTP/관리 API로 아무 작업도 수행하지 않는 AMQP 클라이언트의 연결을 산발적으로 거부하기 시작합니다.

이 문제로 인해 앱이 중단되기 시작하는 경우 다음 두 가지 중 하나를 수행해야 합니다. * 전체 메시징 클러스터를 다시 시작합니다. 이는 일시적인 가동 중지 시간을 초래하고 이 프로세스 중에 메시지가 삭제될 수 있다는 점에서 좋지 않습니다. * 관리 API의 데이터베이스를 다시 시작하고 제거합니다. 이는 관리 API를 사용할 수 없기 때문에 나쁘고, 더 나쁜 것은 다음과 같이 전체 클러스터를 다시 시작할 때까지 제대로 다시 시작되지 않는 방식으로 관리 API를 중단시키는 경우가 많기 때문입니다. 첫 번째 총알.

유사한 문제로 고통받는 대부분의 사람들은 RabbitMQ 3.*으로 업그레이드하여 문제를 해결합니다. 우리는 그러한 프로젝트에 대한 시간, 허가 또는 가동 중지 시간 승인을 갖고 있지 않습니다. 이 문제로 인해 클러스터를 다시 시작할 때 몇 분 동안 주기적인 중단이 발생하더라도 업그레이드 권한이 부여되지 않았습니다. 순전히 정치적 제약이지만 불행한 현실이다.

질문:

가까운 시일 내에 RabbitMQ를 업그레이드할 수 없고 관리 API를 계속 사용해야 하는 경우 메시징 클러스터 오류를 일으키는 지속적이고 오래된 연결 문제를 어떻게 해결할 수 있습니까?

rabbitmqctl우리는 새롭거나 다른 클라이언트 코드를 개발하고 메시징 서버 자체에서 작업을 실행할 수 있지만 로컬로 또는 ssh클라이언트 시스템을 통해 사용할 수 있는 능력은 없습니다 .

우리가 시도한 것:

  • 우리는 더 나은 클라이언트가 자동으로 정리되고 오래된 연결을 남기지 않기를 바라면서 AMQP 클라이언트 라이브러리를 전환해 보았으나 소용이 없었습니다. 문제가 지속됩니다.
  • 우리는 RabbitMQ 서버 자체에서 tcp_keepalive및 TCP 설정을 사용해 보았습니다 . exit_on_close이러한 값을 조합해도 문제가 해결되지 않습니다.
  • JSON API의 연결 목록에서 반환된 모든 연결을 반복하고 사용 중인 경우 필요한 것보다 오랫동안 열려 있는 각 연결에 대해 DELETE를 보내는 스크립트를 만들었습니다. 이러한 모든 요청에는 위에 링크된 SO 질문에 설명된 대로 500개의 서버 오류가 발생합니다.

답변1

주기적으로 모든 것을 계속 다시 시작합니다.

다른 옵션은 수정 사항을 3.x에서 현재 버전으로 백포트하는 것입니다. 그러나 업그레이드가 허용되지 않으면 이 작업도 허용되지 않을 것입니다. 그리고 특히 RabbitMQ 코드가 크게 리팩토링된 경우에는 업그레이드하는 것보다 훨씬 더 많은 작업이 필요할 것입니다.

변경할 수 있을 때까지정치상황에 따라 그것은 귀하의 선택입니다.

관련 정보