Permintaan RPC amqp musim semi ke Rabbitmq mendapatkan batas waktu

Saya menggunakan fungsi AmqpTemplate.sendAndReceive dari beberapa server, ini berfungsi dan koneksi ulang berfungsi setelah Rabbitmq dimulai ulang atau masalah jaringan.

Ini bekerja dengan baik selama beberapa minggu tetapi tiba-tiba salah satu server saya mendapatkan waktu tunggu untuk setiap panggilan sendAndReceive, kelincimq menerima pesan dan sedang diproses tetapi sendAndReceive tidak mendapatkan respons (batas waktu balasan disetel ke 60 detik dan itu hanya membutuhkan beberapa detik untuk memproses pesan). Server lain bekerja pada waktu yang sama dengan kode yang sama dan menggunakan antrian yang sama.

Server kembali berfungsi hanya setelah saya memulai ulang layanannya.

Saya rasa ini ada masalah penyambungan ulang (walaupun pesan berhasil dikirim ke kelincimq), mungkin pendengar respons AmqpTemplate tidak menyambung kembali atau semacamnya.

Adakah yang tahu apa masalahnya? dan bagaimana saya bisa mencegah hal itu terjadi lagi?

pengaturan ConnectionFactory saya:

setConnectionTimeout(1000);
setRequestedHeartbeat(100);
setTopologyRecoveryEnabled(true);
setAutomaticRecoveryEnabled(true);

Sunting:

Versi pegas-AMQP: 1.4.3

<bean id="myConnectionFactory" class="path.to.myConnectionFactoryClass"></bean>

<rabbit:connection-factory id="myRabbitConnectionFactory" connection-factory="myConnectionFactory" channel-cache-size="25" />

<rabbit:template id="myTemplate" connection-factory="myRabbitConnectionFactory" reply-timeout="65000" />

Sunting:

Itu terjadi lagi, saya melihatnya berhenti berfungsi setelah saya mendapatkan kesalahan:

org.springframework.amqp.AmqpConnectException: com.rabbitmq.client.AlreadyClosedException: connection is already closed due to connection error; cause: java.io.EOFException
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:51)
at org.springframework.amqp.rabbit.connection.RabbitAccessor.convertRabbitAccessException(RabbitAccessor.java:110)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1051)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1028)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doSendAndReceiveWithTemporary(RabbitTemplate.java:902)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doSendAndReceive(RabbitTemplate.java:894)
at org.springframework.amqp.rabbit.core.RabbitTemplate.sendAndReceive(RabbitTemplate.java:820)
at MyClass.onMessage(MyClass.java:1234)
at sun.reflect.GeneratedMethodAccessor3558.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy95.onMessage(Unknown Source)
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:237)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:756)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:167)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1241)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:660)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1005)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$100(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$2.doInTransaction(SimpleMessageListenerContainer.java:975)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$2.doInTransaction(SimpleMessageListenerContainer.java:968)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:968)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1103)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.rabbitmq.client.AlreadyClosedException: connection is already closed due to connection error; cause: java.io.EOFException
at com.rabbitmq.client.impl.AMQConnection.ensureIsOpen(AMQConnection.java:174)
at com.rabbitmq.client.impl.AMQConnection.createChannel(AMQConnection.java:496)
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.createChannel(AutorecoveringConnection.java:96)
at org.springframework.amqp.rabbit.connection.SimpleConnection.createChannel(SimpleConnection.java:42)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$ChannelCachingConnectionProxy.createBareChannel(CachingConnectionFactory.java:747)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$ChannelCachingConnectionProxy.access$300(CachingConnectionFactory.java:736)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.doCreateBareChannel(CachingConnectionFactory.java:416)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createBareChannel(CachingConnectionFactory.java:392)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.access$500(CachingConnectionFactory.java:75)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:623)
at com.sun.proxy.$Proxy74.basicCancel(Unknown Source)
at org.springframework.amqp.rabbit.core.RabbitTemplate$7.doInRabbit(RabbitTemplate.java:944)
at org.springframework.amqp.rabbit.core.RabbitTemplate$7.doInRabbit(RabbitTemplate.java:902)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1045)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1028)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doSendAndReceiveWithTemporary(RabbitTemplate.java:902)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doSendAndReceive(RabbitTemplate.java:894)
at org.springframework.amqp.rabbit.core.RabbitTemplate.sendAndReceive(RabbitTemplate.java:820)

Tidak yakin mengapa sambungan ditutup dan mengapa tidak tersambung kembali.


person Ido Ganzer    schedule 09.06.2015    source sumber
comment
Harap berikan konfigurasi lengkap dan versi Spring AMQP. Spring AMQP memiliki mekanisme pemulihan koneksinya sendiri (yang sudah lama ada sebelum versi klien kelinci). Versi sebelum 1.4 tidak kompatibel dengan Rabbitmq automaticRecoveryEnabled.   -  person Gary Russell    schedule 09.06.2015
comment
Terima kasih Gary atas komentar Anda, saya menggunakan v1.4.3 dan saya mengedit postingan dengan info konfigurasi lebih lanjut.   -  person Ido Ganzer    schedule 09.06.2015
comment
Ini adalah pengaturan yang cukup sederhana; tidak ada yang perlu dipulihkan di pihak penerima karena ia menggunakan balasan langsung (atau antrian sementara, bergantung pada versi Rabbitmq) untuk balasannya; apakah Anda melihat sesuatu yang berguna di log? (aplikasi ini dan/atau log kelincimq).   -  person Gary Russell    schedule 09.06.2015
comment
Itu terjadi lagi, saya melihatnya berhenti berfungsi setelah saya mendapatkan kesalahan: com.rabbitmq.client.AlreadyClosedException: koneksi sudah ditutup karena kesalahan koneksi; penyebab: java.io.EOFException   -  person Ido Ganzer    schedule 23.06.2015
comment
di org.springframework.amqp.rabbit.connection.RabbitAccessor.convertRabbitAccessException(RabbitAccessor.java:110) di org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1051)   -  person Ido Ganzer    schedule 23.06.2015
comment
Mengapa koneksinya bisa terputus? dan mengapa tidak tersambung kembali?   -  person Ido Ganzer    schedule 23.06.2015
comment
Anda perlu menunjukkan jejak tumpukan lengkap - jangan letakkan jejak tumpukan di komentar; edit pertanyaannya.   -  person Gary Russell    schedule 23.06.2015
comment
Saya menambahkan stacktrace penuh, terima kasih Gary.   -  person Ido Ganzer    schedule 24.06.2015


Jawaban (2)


di org.springframework.amqp.rabbit.core.RabbitTemplate.sendAndReceive(RabbitTemplate.java:820)

di MyClass.onMessage(MyClass.java:1234) ...

Jadi ini bukan pemulihan sisi server; MyClass Anda menjalankan operasi kirim dan terima templat kelinci lainnya setelah menerima pesan. Jadi ia bertindak sebagai klien dalam situasi ini.

Namun, biasanya, pengecualian ini akan dilemparkan ke penampung, dan kelincimq akan mengirim ulang pesan tersebut (kecuali Anda memiliki mode konfirmasi NONE), selama pendengar Anda melemparkan pengecualian tersebut ke penampung. Jika pendengar Anda menangkap pengecualian dan tidak melakukan apa pun kecuali mencatat, Anda akan melihat hasil ini.

Jika Anda tidak ingin kelinci mengirim ulang pesan yang gagal, atau wadah masuk tidak mengakui pesan, Anda dapat mengonfigurasi RetryTemplate ke dalam templat kelinci keluar untuk memulihkan koneksi; lihat dokumentasi.

Jika ini tidak menjelaskan situasi Anda, Anda perlu menunjukkan konfigurasi lengkap, kode di MyClass.onMessage() dan log lengkap.

person Gary Russell    schedule 24.06.2015

Saya pikir ini sedang diselesaikan. Saya tidak menemukan pengecualian di OnMesaage, dan saya yakin hal itu mematikan pendengar saya.

person Ido Ganzer    schedule 07.07.2015