30.7. 페일오버 모드

JBoss EAP 메시징은 다음 두 가지 유형의 클라이언트 페일오버를 정의합니다.

  • 자동 클라이언트 장애 조치
  • 애플리케이션 수준 클라이언트 장애 조치

또한 JBoss EAP 메시징은 동일한 서버에 연결의 100% 투명한 자동 재연결을 제공합니다(예: 일시적인 네트워크 문제인 경우). 이는 동일한 서버에 다시 연결되어 있으며 클라이언트 재커넥션 및 세션 재연결에서 논의된다는 점을 제외하고 장애 조치와 유사합니다.

장애 조치 중에 클라이언트가 영구 또는 임시 대기열에 있는 소비자가 있는 경우 백업 노드의 장애 조치 중에 해당 큐가 자동으로 다시 생성됩니다. 백업 노드에는 영구 대기열에 대한 지식이 없습니다.

30.7.1. 자동 클라이언트 페일오버

JBoss EAP 메시징 클라이언트는 클라이언트에서 연결 오류가 발생하는 경우(실시간 서버 연결) 오류가 발생할 경우 클라이언트가 실패를 감지하고 백업 서버에 다시 연결할 수 있도록 모든 라이브 및 백업 서버에 대한 정보를 수신하도록 구성할 수 있습니다. 그런 다음 백업 서버는 페일오버 전에 각 연결에 존재하는 모든 세션과 소비자를 자동으로 다시 생성하므로 사용자가 수동 재커넥션 논리를 직접 코딩하지 않아도 됩니다.

JBoss EAP 메시징 클라이언트는 Detecting Dead Connections 에 설명된 대로 client-failure-check-period 에서 지정한 시간 내에 서버에서 패킷을 수신하지 않은 경우 연결 오류를 감지합니다.

클라이언트가 할당된 시간 내에 데이터를 수신하지 않으면 연결이 실패하고 페일오버를 시도했다고 가정합니다. 운영 체제에서 소켓을 닫는 경우 서버 하드웨어가 충돌하는 대신 서버 프로세스가 종료될 수 있습니다. 클라이언트가 즉시 페일오버합니다.

JBoss EAP 메시징 클라이언트는 다양한 방법으로 라이브 백업 서버 쌍 목록을 검색하도록 구성할 수 있습니다. 예를 들어 명시적 엔드포인트를 사용하여 구성할 수 있지만 가장 일반적인 방법은 클라이언트가 먼저 클러스터에 연결할 때 클러스터 토폴로지에 대한 정보를 받는 것입니다. 자세한 내용은 Server Discovery 를 참조하십시오.

기본 HA 구성에는 클러스터 통신에 권장되는 http-connector를 사용하는 cluster- connection 이 포함됩니다. 이는 원격 클라이언트가 기본 RemoteConnectionFactory 를 사용하여 서버에 연결할 때 사용하는 http-connector 와 동일합니다. 권장되지 않지만 다른 커넥터를 사용할 수 있습니다. 고유한 커넥터를 사용하는 경우 원격 클라이언트와 클러스터 노드에서 사용하는 cluster -connection 모두 connection-factory 에 대한 구성의 일부로 포함되어 있는지 확인합니다. 커넥터 및 클러스터 연결에 대한 자세한 내용은 메시징 전송 및 클러스터 연결 구성을 참조하십시오.

주의

자카르타 메시징 클라이언트가 사용할 connection-factory 에 정의된 커넥터 는 클러스터에서 사용하는 cluster-connection 에 정의된 것과 동일해야 합니다. 그렇지 않으면 클라이언트에서 기본 라이브/백업 쌍의 토폴로지를 업데이트할 수 없으므로 백업 서버의 위치를 알 수 없습니다.

CLI 명령을 사용하여 connection -factory 및 cluster- connection 의 구성을 검토합니다. 예를 들어 RemoteConnectionFactory 라는 connection-factory 의 현재 구성을 읽으려면 다음 명령을 사용합니다.

/subsystem=messaging-activemq/server=default/connection-factory=RemoteConnectionFactory:read-resource

마찬가지로 아래 명령은 my-cluster 라는 cluster-connection 에 대한 구성을 읽습니다.

/subsystem=messaging-activemq/server=default/cluster-connection=my-cluster:read-resource

자동 클라이언트 장애 조치를 활성화하려면 0이 아닌 재커넥션 시도를 허용하도록 클라이언트를 구성해야 합니다. 자세한 내용은 클라이언트 재커넥션 및 세션 재연결 을 참조하십시오. 기본적으로 장애 조치는 라이브 서버에 대해 하나 이상의 연결이 완료된 후에만 발생합니다. 즉, 클라이언트가 라이브 서버에 초기 연결하지 못하는 경우 페일오버가 발생하지 않습니다. 초기 시도에 실패하는 경우 클라이언트는 reconnect-attempts 속성에 따라 라이브 서버에 대한 연결을 재시도하고 구성된 횟수 이후에 실패합니다.

/subsystem=messaging-activemq/server=default/connection-factory=RemoteConnectionFactory:write-attribute(name=reconnect-attempts,value=<NEW_VALUE>)

이 규칙의 예외는 백업 서버 및 다른 라이브 서버가 없는 한 쌍의 라이브 서버만 있고 원격 MDB가 라이브 서버에 연결되어 있는 경우입니다. MDB에서 @ActivationConfigProperty(propertyName = "rebalanceConnections", propertyValue = "true") 를 구성한 경우 해당 연결을 다른 라이브 서버로 리밸런싱하려고 시도하고 백업에 장애 조치(failover)하지 않습니다.

초기 연결에서 오버 페일오버

클라이언트에서 첫 번째 연결이 완료된 후에 전체 토폴로지를 알지 못하므로 백업에 대해 모르는 시간이 있습니다. 이 시점에 오류가 발생하면 클라이언트는 원래 라이브 서버에만 다시 연결할 수 있습니다. 클라이언트에서 시도 횟수를 구성하려면 ClientSessionFactoryImpl 또는 ActiveMQConnectionFactory 에서 속성 initialConnectAttempts 를 설정할 수 있습니다.

또는 서버 구성에서 클라이언트에서 사용하는 연결 팩토리의 initial-connect-attempts 특성을 설정할 수 있습니다. 기본값은 0, 즉 한 번만 시도합니다. 시도 횟수가 완료되면 예외가 발생합니다.

/subsystem=messaging-activemq/server=default/connection-factory=RemoteConnectionFactory:write-attribute(name=initial-connect-attempts,value=<NEW_VALUE>)
서버 복제 정보

JBoss EAP 메시징은 라이브 서버와 백업 서버 간에 전체 서버 상태를 복제하지 않습니다. 백업에서 새 세션이 자동으로 다시 생성되면 해당 세션 중에 전송되거나 승인된 메시지에 대한 지식은 없습니다. 페일오버 시점에 진행 중인 모든 전송 또는 승인이 손실될 수 있습니다.

JBoss EAP 메시징은 전체 서버 상태를 복제함으로써 이론적으로 100% 투명한 페일오버를 제공하여 메시지나 감사가 손실되지 않도록 할 수 있었습니다. 그러나 이 작업을 수행하는 것은 대기열 및 세션을 포함하여 전체 서버 상태를 복제하는 데 큰 비용이 듭니다. 이를 위해서는 전체 서버 상태 시스템의 복제가 필요합니다. 즉 일관된 복제 상태를 보장하기 위해 실시간 서버의 모든 작업을 정확히 동일한 글로벌 복제 서버에 복제해야 합니다. 여러 스레드가 라이브 서버 상태를 동시에 변경하는 것을 고려하는 것은 고성능이고 확장 가능한 방식으로는 매우 어렵습니다.

가상 신디온과 같은 기술을 사용하여 전체 상태 시스템 복제를 제공할 수 있지만, 제대로 확장되지 않고 모든 작업을 단일 스레드로 직렬화하여 동시성이 크게 줄어듭니다. 잠금 상태 복제 또는 스레드 스케줄링 복제와 같은 다중 스레드 활성 복제 기법이 있지만 이는 Java 수준에서 달성하기가 매우 어렵습니다.

결과적으로 100% 투명한 페일오버를 위해 성능과 동시성을 줄일 필요가 없었습니다. 100% 투명한 페일오버가 없어도 중복 탐지와 트랜잭션 재시도를 사용하여 실패하는 경우에도 한 번만 간편하게 제공할 수 있습니다. 그러나 클라이언트 코드에 100% 투명하지는 않습니다.

30.7.1.1. 페일오버 중 차단 호출 처리

클라이언트 코드가 서버에 대한 호출을 차단하는 경우, 즉, 페일오버 중에 새 세션에 진행 중인 호출에 대한 정보가 없습니다. 차단된 호출은 영속적으로 중단될 수 있으며, 전달되지 않을 응답을 기다립니다.

이를 방지하기 위해 JBoss EAP 메시징은 장애 조치 시 진행 중인 모든 차단 호출을 차단 해제합니다. javax.jms.JMSException, Jakarta Messaging을 사용하는 경우 또는 코어 API를 사용하는 경우 오류 코드 ActiveMQException.UNBLOCKED를 사용하여 ActiveMQException.UNBLOCKED 가 있는 ActiveMQException. 클라이언트 코드에서 이 예외를 감지하고 필요한 경우 작업을 다시 시도합니다.

unblocked 메서드가 commit() 또는 prepare() 호출인 경우, 코어 API를 사용하는 경우 트랜잭션이 자동으로 롤백되고 JBoss EAP 메시징에서 javax.jms.TransactionRolledBackException, Jakarta Messaging을 사용하는 경우 오류 코드 ActiveMQException.TRANSACTION_ROLLED_BACK 가 있는 ActiveMQException이 발생합니다.

30.7.1.2. 트랜잭션을 사용하여 페일오버 처리

세션이 트랜잭션 중이고 현재 트랜잭션에서 메시지가 이미 전송되거나 승인된 경우 서버에서 장애 조치 중에 메시지 또는 승인이 손실되었는지 확인할 수 없습니다.

결과적으로 트랜잭션은 롤백 전용으로 표시되며, 코어 API를 사용하는 경우 javax.jms.TransactionRolledBackException, 즉 오류 코드 ActiveMQException. TRANSACTION_ROLLED_BACK가 발생하게 됩니다. 코어 API를 사용하는 경우 오류 코드 ActiveMQException.TRANSACTION_ROLLED_BACK 가 있는 ActiveMQException.

주의

이 규칙의 주의 사항은 XA를 자카르타 메시징을 통해 또는 핵심 API를 통해 사용할 때입니다. 2단계 커밋을 사용하고 prepare() 가 이미 호출된 경우 롤백하면 HeuristicMixedException 이 발생할 수 있습니다. 이로 인해 커밋에 XAException.XA_RETRY 예외가 발생합니다. 이는 트랜잭션 관리자가 나중에 커밋을 다시 시도해야 한다는 것을 알립니다. 부작용으로 인해 지속되지 않는 메시지가 손실됩니다. 이 문제가 발생하지 않도록 하려면 XA를 사용할 때 영구 메시지를 사용해야 합니다. prepare() 가 호출되기 전에 서버에 플러시되므로 이 문제는 문제가 되지 않습니다.

사용자가 예외를 감지하고 필요에 따라 클라이언트 측 로컬 롤백 코드를 수행합니다. 이미 롤백되었으므로 세션을 수동으로 롤백할 필요가 없습니다. 사용자는 동일한 세션에서 트랜잭션 작업을 다시 시도할 수 있습니다.

커밋 호출이 실행될 때 페일오버가 발생하면 이전에 설명한 대로 서버는 응답이 반환되지 않으므로 호출 차단을 해제하여 중지를 방지합니다. 이 경우 클라이언트가 오류가 발생하기 전에 실시간 서버에서 트랜잭션 커밋이 실제로 처리되었는지 여부를 쉽게 확인할 수 없습니다.

참고

XA가 Jakarta Messaging 또는 코어 API를 통해 사용되는 경우 XAException.XA_RETRY 가 throw됩니다. 이는 트랜잭션 관리자에게 특정 시점에 재시도가 수행되어야 함을 알리는 것입니다. 나중에 트랜잭션 관리자가 커밋을 다시 시도합니다. 원래 커밋이 발생하지 않은 경우 계속 존재하며 커밋됩니다. 트랜잭션 관리자가 경고를 기록할 수 있지만 커밋된 것으로 가정됩니다.

이를 해결하기 위해 클라이언트는 트랜잭션에서 중복 탐지를 활성화하고 호출이 차단 해제된 후 트랜잭션 작업을 다시 시도할 수 있습니다. 서버에 탐지를 구성하는 방법에 대한 자세한 내용은 메시지 탐지 중복 을 참조하십시오. 실제로 페일오버 전에 트랜잭션이 라이브 서버에 커밋된 경우 중복 탐지는 트랜잭션에 있는 지속적 메시지를 무시하여 트랜잭션 재시도 시 두 번 이상 전송되지 않도록 합니다.

30.7.1.3. 연결 오류 알림 받기

Jakarta Messaging은 연결 실패 비동기 알림( java.jms.ExceptionListener )을 전송하는 표준 메커니즘을 제공합니다. 이 수업에 대한 자세한 내용은 Jakarta Messaging javadoc 를 참조하십시오. 또한 핵심 API는 org.apache.activemq.artemis.core.client.SessionFailureListener 클래스의 형태로 유사한 기능을 제공합니다.

연결이 성공적으로 실패했는지 여부에 관계없이 ExceptionListener 또는 SessionFailureListener 인스턴스는 연결 실패 시 JBoss EAP에서 항상 호출됩니다. 그러나 SessionfailureListenerconnectionFailed() 또는 다음 중 하나일 javax.jms.JMSException의 error 코드에 전달된 failedOver 플래그의 값을 검사하여 재연결 또는 재연결이 발생했는지 확인할 수 있습니다.

JMSException 오류 코드

오류 코드설명

페일오버

페일오버가 발생했으며 성공적으로 다시 연결 또는 재연결되었습니다.

연결 끊기

페일오버가 발생하지 않았으며 연결이 끊어졌습니다.

30.7.2. 애플리케이션 레벨 페일오버

경우에 따라 자동 클라이언트 페일오버를 원하지 않을 수 있으며 연결 오류를 직접 처리하고 자체 장애 처리기에서 직접 직접 재커넥션 논리를 코딩하는 것을 선호할 수 있습니다. 페일오버는 사용자 애플리케이션 수준에서 처리되므로 이를 애플리케이션 수준 장애 조치(failover)로 정의합니다.

Jakarta Messaging을 사용하는 경우 애플리케이션 수준 페일오버를 구현하려면 Jakarta Messaging 연결에 ExceptionListener 클래스를 설정합니다. 연결 오류가 감지되는 경우 JBoss EAP 메시징에서 ExceptionListener 를 호출합니다. ExceptionListener 에서는 이전 Jakarta Messaging 연결을 닫고 JNDI에서 새로운 연결 팩토리 인스턴스를 찾고 새 연결을 생성할 수 있습니다.

코어 API를 사용하는 경우 절차가 매우 유사합니다. 핵심 ClientSession 인스턴스에 FailureListener 를 설정합니다.