2013-04-25 4 views
0

ActiveMQ을 사용하여 일부 이벤트에 대한 JMS 메시지를 보내는 메시지 생성자가 있습니다. 그러나 ActiveMQ에 대한 연결이 항상 켜져 있지 않을 수 있습니다. 따라서 이벤트가 저장되고 연결이 설정되면 읽기 및 전송되는 것으로 가정합니다. 여기 내 코드입니다 :JMS 연결이 설정되면 어떻게 잡을 수 있습니까?

private void sendAndSave(MyEvent event) { 
    boolean sent = sendMessage(event); 
    event.setProcessed(sent); 
    boolean saved = repository.saveEvent(event); 
    if (!sent && !saved) { 
     logger.error("Change event lost for Id = {}", event.getId()); 
    } 
} 

private boolean sendMessage(MyEvent event) { 
    try { 
     messenger.publishEvent(event); 
     return true; 
    } catch (JmsException ex) { 
     return false; 
    } 
} 
내가 연결이 설정 및 프로세스 보내지 않은 사건 때 호출됩니다 어떤 종류의 ApplicationEventListener를 만들 싶습니다

. JMS, Spring 프레임 워크 및 ActiveMQ 문서를 살펴 봤지만 ConnectionFactory를 사용하여 리스너를 연결하는 방법을 찾을 수 없습니다.

누군가 나를 도울 수 있으면 크게 감사하겠습니다. 여기

내 응용 프로그램 Spring 컨텍스트가 JMS에 대해 말씀입니다 :

<!-- Connection factory to the ActiveMQ broker instance.    --> 
<!-- The URI and credentials must match the values in activemq.xml --> 
<!-- These credentials are shared by ALL producers.     --> 
<bean id="jmsTransportListener" class="com.rhd.ams.service.common.JmsTransportListener" 
     init-method="init" destroy-method="cleanup"/> 
<bean id="amqJmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 
    <property name="brokerURL" value="${jms.publisher.broker.url}"/> 
    <property name="userName" value="${jms.publisher.username}"/> 
    <property name="password" value="${jms.publisher.password}"/> 
    <property name="transportListener" ref="jmsTransportListener"/> 
</bean> 

<!-- JmsTemplate, by default, will create a new connection, session, producer for   --> 
<!-- each message sent, then close them all down again. This is very inefficient!   --> 
<!-- PooledConnectionFactory will pool the JMS resources. It can't be used with consumers.--> 
<bean id="pooledAmqJmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 
    <property name="connectionFactory" ref="amqJmsConnectionFactory" /> 
</bean> 

<!-- Although JmsTemplate instance is unique for each message, it is --> 
<!-- thread-safe and therefore can be injected into referenced obj's. --> 
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 
    <constructor-arg ref="pooledAmqJmsConnectionFactory"/> 
</bean> 
+0

당신이 정교하게 설정해야합니다. 장애 조치 전송 등을 사용하고 있습니까? –

+0

원본 메시지에 Spring app context를 추가했습니다. –

+0

연결 URI를 생략하기 때문에 여전히 쓸모가 없습니다. –

답변

1

당신이 문제를 설명하는 방법, 그것은 확실히 JMS 영구 가입의 오픈과-종료의 경우처럼 들린다. 이 길을 가기 전에 더 전통적인 구현을 고려할 수도 있습니다. 주의 사항을 제외하면 ActiveMQ는 청취 할 수 있고 새로운 연결을 포함하여 다양한 이벤트를 위해 전송되는 Advisory Messages을 제공합니다.

=========

촬영은, 죄송합니다 ... 나는 문제가 무엇인지 이해하지 못했다. 나는 권고가 전혀 해결책이라고 생각하지 않습니다. 결국, 당신은 브로커와 연결되어 있어야합니다. 그러나 연결되는 것은 당신이 알고있는 것입니다.

그래서 제대로 이해하면 (재시도 # 2 준비 ...), 클라이언트 연결에 실패하면 무한정 재 연결을 시도하는 클라이언트 연결이 필요합니다. 다시 연결되면 보류중인 메시지를 브로커에 플러시하는 이벤트 (또는 그 이상)를 트리거하려고합니다.

그래서 연결이 끊어지는 것을 쉽게 감지 할 수 있습니다. JMS ExceptionListener을 등록하기 만하면됩니다. 늘어나는만큼 재접속을, 내가 생각할 수있는 가장 간단한 방법은 다시 연결 스레드를 시작하는 것입니다. 연결되면 재접속 스레드를 중지하고 Observer/Observable 또는 JMX 알림 등을 사용하여 이해 관계자에게 알립니다. 브로커가 하나만있는 경우에도 연결 재시도 루프를 수행 할 ActiveMQ Failover Transport을 사용할 수 있습니다. 적어도, 그것은 supposed to이지만, 그것은 당신 자신의 재접속 스레드에 의해 수행되지 않을 많은 것을하고 있지 않습니다 ... 그러나 만약 당신이 어떤 컨트롤을 위임하고 싶다면, 당신의 unflushed 메시지를 캐쉬 할 것입니다. trackMessages 옵션을 참조하십시오). 그런 다음 재 연결될 때 보내십시오. 이는 수행하려는 모든 작업입니다.

브로커가 몇 분간 다운 된 경우에도 나쁘지는 않겠지 만 몇 시간 만 이야기하거나 다운 타임에 1 만 + 메시지가 누적 될 수 있습니다. 캐시 메커니즘은 필요한만큼 신뢰할 수 있습니다.

==================

모바일 앱 ... 좋아. 장애 조치 전송에는 적합하지 않습니다. 그런 다음 주기적으로 연결하는 타이머를 구현합니다 (http 전송을 사용하는 것이 좋지만 관련이 없음). 연결될 때 플러시 할 것이 없으면 x 분 후에 만나십시오.있을 경우 각 메시지를 보내고 핸드 셰이크를 기다리고 모바일 저장소에서 메시지를 제거합니다. x 분 후에 다시 만나요.

Android라고 가정합니다. 그렇지 않은 경우 여기에서 읽지 마십시오. 우리는 실제로 이것을 얼마 전에 구현했습니다. 나는 서버 측 만 기억하지만, 정확하게 기억한다면 연결 타이머/폴러는 매 n 분마다 회전합니다 (가변 주파수는 너무 공격적으로 배터리를 소모하기 때문에 생각합니다). 성공적인 연결이 이루어지면 메시지 푸시 쳐가 자신의 일을하기 위해 의도 된 방송을 사용했다고 생각합니다. 비록 메시지 푸시자가 단 한 명이라도 더 많은 것을 추가 할 수 있다고 생각했습니다.

+0

JMS 영구 가입과 같지 않습니다. 영구 가입 메시지의 정의에 따라 구독자는 JMS 연결을 벗어날 수 있으며 마지막으로 연결할 때 이러한 메시지를 받게됩니다. 필자의 경우 메시지 생성자는 JMS 연결이 느슨하지만 생성 된 모든 메시지를 저장합니다. 연결이되면 모든 보내지 않은 메시지를 보내야합니다. ActiveMQ 권고 지원에 대해서는 해결책 일 수 있지만 CONNECTION_ADVISORY_TOPIC 메시지가 전달하는 정보를 찾을 수 없습니다. 구글 검색이 도움이되지 못했습니다. 어떤 코드 예제를 알고 있습니까? –

+0

원본 답변이 업데이트되었습니다. – Nicholas

+0

내 자신의 재 연결 루프를 만들면 ActiveMQ 장애 조치 전송을 방해 할 수 있습니까? ActiveMQ Failover Transport가 재시도 루프를 처리하는 경우 연결이 다시 설정되었다는 것을 응용 프로그램에 어떻게 알릴 수 있습니까? ActiveMQ Failover Transport에서 제공하는 캐시 크기가 너무 작습니다. 클라이언트가 모바일 앱이며 몇 시간 동안 WIFI에서 떨어져있을 수 있습니다. 보내지 않은 이벤트를 디스크에 저장하고 있습니다. –

관련 문제