2017-04-04 11 views
2

春の作業、私はrabbitmqに新しいです、私はどこが間違っているか知りたいです。春のrabbitmqリスナーの例外処理

私はrabbitmq接続ファクトリとリスナーを含むリスナーコンテナを作成しました。また、リスナーコンテナにエラーハンドラを提供しましたが、うまくいきません。

私の春の豆:

<rabbit:connection-factory id="RabbitMQConnectionFactory" virtual-host="${rabbitmq.vhost}" host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}"/> 
<rabbit:listener-container missing-queues-fatal="false" declaration-retries="0" error-handler="errorHandlinginRabbitMQ" recovery-interval="10000" auto-startup="${rabbitmq.apc.autostartup}" max-concurrency="1" prefetch="1" concurrency="1" connection-factory="RabbitMQConnectionFactory" acknowledge="manual"> 
    <rabbit:listener ref="apcRabbitMQListener" queue-names="${queue.tpg.rabbitmq.destination.apc}" exclusive="true" /> 
</rabbit:listener-container> 
<bean id="errorHandlinginRabbitMQ" class="RabbitMQErrorHandler"/> 

これは私のRabbitMQErrorHandlerクラスです:私は、接続ファクトリに無効な資格情報を提供する場合

public class RabbitMQErrorHandler implements ErrorHandler 
{ 
    @Override 
    public void handleError(final Throwable exception) 
    { 
     System.out.println("error occurred in message listener and handled in error handler" + exception.toString()); 
    } 
} 

何私が仮定することは、RabbitMQErrorHandlerクラスのhandleErrorのメソッドである必要がありますサーバーが正常に起動するはずですが、サーバーを実行しようとすると、メソッドが実行されず(例外がコンソールにスローされます)、サーバーを起動できません。どこが何か不足していて、それが何であるか?

答えて

3

エラーハンドラは、メッセージ配信中のエラーを処理するためのものです。まだ接続していないので、エラーを処理するメッセージはありません。

接続例外を取得するには、ApplicationListener<ListenerContainerConsumerFailedEvent>を実装する必要があります。アプリケーションコンテキストにBeanとして追加すると、イベントとしてエラーが発生します。

ApplicationListener<AmqpEvent>を実装すると、他のイベント(コンシューマーが開始した、コンシューマーが停止したなど)が表示されます。

EDIT

<rabbit:listener-container auto-startup="false"> 
    <rabbit:listener id="fooContainer" ref="foo" method="handleMessage" 
       queue-names="si.test.queue" /> 
</rabbit:listener-container> 

<bean id="foo" class="com.example.Foo" /> 

はFoo:

public class Foo { 

    public final CountDownLatch latch = new CountDownLatch(1); 

    public void handleMessage(String foo) { 
     System.out.println(foo); 
     this.latch.countDown(); 
    } 

} 

アプリケーション:

@SpringBootApplication 
@ImportResource("context.xml") 
public class So43208940Application implements CommandLineRunner { 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = SpringApplication.run(So43208940Application.class, args); 
     context.close(); 
    } 

    @Autowired 
    private SimpleMessageListenerContainer fooContainer; 

    @Autowired 
    private CachingConnectionFactory connectionFactory; 

    @Autowired 
    private RabbitTemplate template; 

    @Autowired 
    private Foo foo; 

    @Override 
    public void run(String... args) throws Exception { 
     this.connectionFactory.setUsername("junk"); 
     try { 
      this.fooContainer.start(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     Thread.sleep(5000); 
     this.connectionFactory.setUsername("guest"); 
     this.fooContainer.start(); 
     System.out.println("Container started"); 
     this.template.convertAndSend("si.test.queue", "foo"); 
     foo.latch.await(10, TimeUnit.SECONDS); 
    } 

} 
+0

おかげで、それが働きました。私は実行したいメソッドは、しかし、それはまだサーバーが適切に起動することを許可しませんでした。リスナーのいくつかの例外のために、リスナーがアクティブ化されていなくても、サーバー上のサービスの残りの部分は機能し続けます。ご案内ください –

+0

認証エラーは致命的とみなされます。 'auto-startup =" false "'を設定し、例外を捕捉できるようにコンテナを手動で起動することができます。 –

+0

と、手動でコンテナを開始するにはどうすればよいですか?それは私が最後の数日から探してきたものです。また、リスナーコンテナに**自動起動**タグがありません –