Activemq message sending Process

Source: Internet
Author: User

1. Message sending Portal

  Message message = messageBean.getMessageCreator().createMessage(session);  producer.send(message);

2. Call the send method of activemqmessageproducersupport. This class implements the messageproducer Interface

 public void send(Message message) throws JMSException {        this.send(this.getDestination(),                  message,                  this.defaultDeliveryMode,                  this.defaultPriority,                  this.defaultTimeToLive);    }        public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, AsyncCallback onComplete) throws JMSException {        checkClosed();        if (destination == null) {            if (info.getDestination() == null) {                throw new UnsupportedOperationException("A destination must be specified.");            }            throw new InvalidDestinationException("Don't understand null destinations");        }        ActiveMQDestination dest;        if (destination.equals(info.getDestination())) {            dest = (ActiveMQDestination)destination;        } else if (info.getDestination() == null) {            dest = ActiveMQDestination.transform(destination);        } else {            throw new UnsupportedOperationException("This producer can only send messages to: " + this.info.getDestination().getPhysicalName());        }        if (dest == null) {            throw new JMSException("No destination specified");        }        if (transformer != null) {            Message transformedMessage = transformer.producerTransform(session, this, message);            if (transformedMessage != null) {                message = transformedMessage;            }        }        if (producerWindow != null) {            try {                producerWindow.waitForSpace();            } catch (InterruptedException e) {                throw new JMSException("Send aborted due to thread interrupt.");            }        }        this.session.send(this, dest, message, deliveryMode, priority, timeToLive, producerWindow, sendTimeout, onComplete);        stats.onMessage();    }

3. Call the send API of activemqsession to send messages.

protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination, Message message, int deliveryMode, int priority, long timeToLive,                        MemoryUsage producerWindow, int sendTimeout, AsyncCallback onComplete) throws JMSException {        checkClosed();        if (destination.isTemporary() && connection.isDeleted(destination)) {            throw new InvalidDestinationException("Cannot publish to a deleted Destination: " + destination);        }        synchronized (sendMutex) {            // tell the Broker we are about to start a new transaction            doStartTransaction();            TransactionId txid = transactionContext.getTransactionId();            long sequenceNumber = producer.getMessageSequence();            //Set the "JMS" header fields on the original message, see 1.1 spec section 3.4.11            message.setJMSDeliveryMode(deliveryMode);            long expiration = 0L;            if (!producer.getDisableMessageTimestamp()) {                long timeStamp = System.currentTimeMillis();                message.setJMSTimestamp(timeStamp);                if (timeToLive > 0) {                    expiration = timeToLive + timeStamp;                }            }            message.setJMSExpiration(expiration);            message.setJMSPriority(priority);            message.setJMSRedelivered(false);            // transform to our own message format here            ActiveMQMessage msg = ActiveMQMessageTransformation.transformMessage(message, connection);            // Set the message id.            if (msg == message) {                msg.setMessageId(new MessageId(producer.getProducerInfo().getProducerId(), sequenceNumber));            } else {                msg.setMessageId(new MessageId(producer.getProducerInfo().getProducerId(), sequenceNumber));                message.setJMSMessageID(msg.getMessageId().toString());            }            //clear the brokerPath in case we are re-sending this message            msg.setBrokerPath(null);            // destination format is provider specific so only set on transformed message            msg.setJMSDestination(destination);            msg.setTransactionId(txid);            if (connection.isCopyMessageOnSend()) {                msg = (ActiveMQMessage)msg.copy();            }            msg.setConnection(connection);            msg.onSend();            msg.setProducerId(msg.getMessageId().getProducerId());            if (LOG.isTraceEnabled()) {                LOG.trace(getSessionId() + " sending message: " + msg);            }            if (onComplete==null && sendTimeout <= 0 && !msg.isResponseRequired() && !connection.isAlwaysSyncSend() && (!msg.isPersistent() || connection.isUseAsyncSend() || txid != null)) {                this.connection.asyncSendPacket(msg);                if (producerWindow != null) {                    // Since we defer lots of the marshaling till we hit the                    // wire, this might not                    // provide and accurate size. We may change over to doing                    // more aggressive marshaling,                    // to get more accurate sizes.. this is more important once                    // users start using producer window                    // flow control.                    int size = msg.getSize();                    producerWindow.increaseUsage(size);                }            } else {                if (sendTimeout > 0 && onComplete==null) {                    this.connection.syncSendPacket(msg,sendTimeout);                }else {                    this.connection.syncSendPacket(msg, onComplete);                }            }        }    }


4. activemqconnection sends messages.

    public Response syncSendPacket(Command command) throws JMSException {        if (isClosed()) {            throw new ConnectionClosedException();        } else {            try {                Response response = (Response)this.transport.request(command);                if (response.isException()) {                    ExceptionResponse er = (ExceptionResponse)response;                    if (er.getException() instanceof JMSException) {                        throw (JMSException)er.getException();                    } else {                        if (isClosed()||closing.get()) {                            LOG.debug("Received an exception but connection is closing");                        }                        JMSException jmsEx = null;                        try {                            jmsEx = JMSExceptionSupport.create(er.getException());                        } catch(Throwable e) {                            LOG.error("Caught an exception trying to create a JMSException for " +er.getException(),e);                        }                        //dispose of transport for security exceptions                        if (er.getException() instanceof SecurityException && command instanceof ConnectionInfo){                            Transport t = this.transport;                            if (null != t){                                ServiceSupport.dispose(t);                            }                        }                        if (jmsEx !=null) {                            throw jmsEx;                        }                    }                }                return response;            } catch (IOException e) {                throw JMSExceptionSupport.create(e);            }        }    }        public Response syncSendPacket(Command command) throws JMSException {        if (isClosed()) {            throw new ConnectionClosedException();        } else {            try {                Response response = (Response)this.transport.request(command);                if (response.isException()) {                    ExceptionResponse er = (ExceptionResponse)response;                    if (er.getException() instanceof JMSException) {                        throw (JMSException)er.getException();                    } else {                        if (isClosed()||closing.get()) {                            LOG.debug("Received an exception but connection is closing");                        }                        JMSException jmsEx = null;                        try {                            jmsEx = JMSExceptionSupport.create(er.getException());                        } catch(Throwable e) {                            LOG.error("Caught an exception trying to create a JMSException for " +er.getException(),e);                        }                        //dispose of transport for security exceptions                        if (er.getException() instanceof SecurityException && command instanceof ConnectionInfo){                            Transport t = this.transport;                            if (null != t){                                ServiceSupport.dispose(t);                            }                        }                        if (jmsEx !=null) {                            throw jmsEx;                        }                    }                }                return response;            } catch (IOException e) {                throw JMSExceptionSupport.create(e);            }        }    }


5. responsecorrelator sends a request

    public Object request(Object command) throws IOException {        FutureResponse response = asyncRequest(command, null);        return response.getResult();    }        public FutureResponse asyncRequest(Object o, ResponseCallback responseCallback) throws IOException {        Command command = (Command) o;        command.setCommandId(sequenceGenerator.getNextSequenceId());        command.setResponseRequired(true);        FutureResponse future = new FutureResponse(responseCallback);        IOException priorError = null;        synchronized (requestMap) {            priorError = this.error;            if (priorError == null) {                requestMap.put(new Integer(command.getCommandId()), future);            }        }        if (priorError != null) {            future.set(new ExceptionResponse(priorError));            throw priorError;        }        next.oneway(command);        return future;    }


6. Call mutextransport to send messages.

    @Override    public void oneway(Object command) throws IOException {        writeLock.lock();        try {            next.oneway(command);        } finally {            writeLock.unlock();        }    }    


7. Call receivactinactivitymonitor to complete message sending preparation.

    public void oneway(Object o) throws IOException {        // To prevent the inactivity monitor from sending a message while we        // are performing a send we take a read lock.  The inactivity monitor        // sends its Heart-beat commands under a write lock.  This means that        // the MutexTransport is still responsible for synchronizing sends        this.sendLock.readLock().lock();        inSend.set(true);        try {            doOnewaySend(o);        } finally {            commandSent.set(true);            inSend.set(false);            this.sendLock.readLock().unlock();        }    }            private void doOnewaySend(Object command) throws IOException {        if( failed.get() ) {            throw new InactivityIOException("Cannot send, channel has already failed: "+next.getRemoteAddress());        }        if (command.getClass() == WireFormatInfo.class) {            synchronized (this) {                processOutboundWireFormatInfo((WireFormatInfo) command);            }        }        next.oneway(command);    }



8. Call tcptransport, openwireformat, and dataoutputstream to send messages over TCP.

   public void oneway(Object command) throws IOException {        checkStarted();        wireFormat.marshal(command, dataOut);        dataOut.flush();    }     public synchronized void marshal(Object o, DataOutput dataOut) throws IOException {        if (cacheEnabled) {            runMarshallCacheEvictionSweep();        }        int size = 1;        if (o != null) {            DataStructure c = (DataStructure)o;            byte type = c.getDataStructureType();            DataStreamMarshaller dsm = (DataStreamMarshaller)dataMarshallers[type & 0xFF];            if (dsm == null) {                throw new IOException("Unknown data type: " + type);            }            if (tightEncodingEnabled) {                BooleanStream bs = new BooleanStream();                size += dsm.tightMarshal1(this, c, bs);                size += bs.marshalledSize();                if (!sizePrefixDisabled) {                    dataOut.writeInt(size);                }                dataOut.writeByte(type);                bs.marshal(dataOut);                dsm.tightMarshal2(this, c, dataOut, bs);            } else {                DataOutput looseOut = dataOut;                if (!sizePrefixDisabled) {                    bytesOut.restart();                    looseOut = bytesOut;                }                looseOut.writeByte(type);                dsm.looseMarshal(this, c, looseOut);                if (!sizePrefixDisabled) {                    ByteSequence sequence = bytesOut.toByteSequence();                    dataOut.writeInt(sequence.getLength());                    dataOut.write(sequence.getData(), sequence.getOffset(), sequence.getLength());                }            }        } else {            if (!sizePrefixDisabled) {            dataOut.writeInt(size);            }            dataOut.writeByte(NULL_TYPE);        }    }        public final void writeInt(int v) throws IOException {        out.write((v >>> 24) & 0xFF);        out.write((v >>> 16) & 0xFF);        out.write((v >>>  8) & 0xFF);        out.write((v >>>  0) & 0xFF);        incCount(4);    }




Diagram


Note: messageid is generated by producerid + sequencenumber. sequencenumber is generated by adding 1 to the atomic variable.



Activemq message sending Process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.