spring - Java RabbitMQ consumer.nextMessage always gets same message -
we using java rabbitmq spring boot in distributed service architecture. 1 service gets http request , forwards unkown queue processing. @ same time has wait response on queue before can terminate http request. (it's preview request gets work done renderer).
there can more 1 instance of servicea (the http interface) , serviceb (the renderer) every preview message send unique id used routing key.
i'm having trouble blockingconsumer. whenever call consumer.nextmessage() same message on , on again. doubly weird, 1 should acked , removed queue , consumer shouldn't bother unique id used no longer bound queue. nextmessage returns before renderer service done , has sent done message back.
here's simplified setup:
general
all services use global directexchange messages
@bean public directexchange globaldirectexchange() { return new directexchange(exchange_name, false, true); }
servicea (handles http request):
private content requestpreviewbykey(rendermessage rendermessage, string previewkey) { string renderdoneroutingkey= uuid.randomuuid().tostring(); rendermessage.setpreviewdonekey(renderdoneid); binding binding = bindingbuilder.bind(previewdonequeue).to(globaldirectexchange) .with(renderdoneroutingkey); try { amqpadmin.declarebinding(binding); rabbitproducer.sendpreviewrequesttokey(rendermessage, previewkey); return getcontentblocking(); } catch (exception e) { logerrorifdebug(type, e); throw new apiexception(baseerrorcode.communication_error, "could not render preview"); } { amqpadmin.removebinding(binding); } } private content getcontentblocking() { blockingqueueconsumer blockingqueueconsumer = new blockingqueueconsumer(rabbitmqconfig.connectionfactory(), new defaultmessagepropertiesconverter(), new activeobjectcounter<>(), acknowledgemode.auto, true, 1, preview_done_queue); try { blockingqueueconsumer.start(); message message = blockingqueueconsumer.nextmessage(waitforpreviewms); if (!stringutils.isempty(message)) { string result = new string(message.getbody()); return jsonutils.stringtoobject(result, content.class); } throw new apiexception("could not render preview"); } catch (exception e) { logerror(e); throw new apiexception("could not render preview"); } { blockingqueueconsumer.stop(); }
}
service b
i'll spare of code. log says going , done service sends correct message uuid key sent initial render request.
public void sendpreviewdonemessage(content content, string previewdonekey) { string message = jsonutils.objecttostring(content); rabbittemplate.convertandsend(globaldirectexchange, previewdonekey, message); }
the whole thing works... once... real issues seems consumer setup. why keep getting same (first) message queue when use nextmessage(). doesn't creating , removing bindung ensure, messages bound routingkey received in instance? , doesn't nextmessage() acknowledge message , remove queue?!
thank's lot bearing me , more helpful answer!
blockingqueueconsumer
not designed used directly; component of simplemessagelistenercontainer
, take care of acking message after has been consumed listener (the container calls commitifnecessary
).
there may other unexpected side effects of using consumer directly.
i advise using listener container consume messages.
if want receive messages on demand, use rabbittemplate
receive()
or receiveandconvert()
method instead.
Comments
Post a Comment