Asynchronous delivery
activemq supports synchronous and asynchronous sending modes to send messages to the broker. The choice of mode has a great impact on the sending delay. The output rate that producer can achieve (output rate = total amount of transmitted data / time) is mainly affected by the transmission delay. Using asynchronous transmission can significantly improve the transmission performance.
activemq uses asynchronous sending mode by default:
Unless the method of synchronous sending is explicitly specified or persistent messages are sent without using transactions, these two cases are synchronous sending to.
If transactions are not used and persistent messages are sent, each message is sent synchronously and the producer will be blocked until the broker returns an acknowledgement, indicating that the message has been safely persisted to the disk. The acknowledgement mechanism provides the guarantee of message security, but blocking the client also brings great delay.
Therefore, it is allowed to lose a small amount of data in case of failure, and asynchronous sending can be used to improve productivity.
Asynchronous sending can maximize the sending efficiency of producer. Generally, asynchronous sending is used when the number of messages sent is relatively dense, which can improve the performance of producer, but there will be additional problems:
It needs to consume more client memory, which will also increase the performance consumption of the broker, and can not effectively ensure the successful sending of messages.
Therefore, when userAsyncSend=true, the client needs to tolerate the possibility of message loss.
Configuration mode: there are 3 types
tcp://106.13.187.36:61616?jms.useAsyncSend=true
activeMQConnectionFactory.setUseAsyncSend(true);
((ActiveMQConnection) connection).setUseAsyncSend(true);
How can asynchronous sending ensure success
Scenario of asynchronous message loss:
Producer sets useAsyncSend=true and uses producer Send (MSG) keeps sending messages.
Since the message is not blocked, the producer will think that all sent messages are successfully sent to mq. However, if mq goes down suddenly, messages that are not sent in the memory of the producer will be lost.
Therefore, correct asynchronous sending requires receiving callback.
Difference between synchronous transmission and asynchronous transmission:
After the synchronous transmission is completed, if the send is not blocked, it means that the transmission is successful
After asynchronous sending, the client needs to receive the receipt and judge whether the sending is successful again
The callback is implemented through ActiveMQMessageProducer. The previous code uses the message sent by MessageProducer
public class JmsProducerAsyncSend { public static final String ACTIVEMQ_URL = "tcp://localhost61616"; public static final String USERNAME = "admin"; public static final String PASSWORD = "hll123"; public static final String QUEUE_NAME = "queue01"; public static void main(String[] args) throws Exception { ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, ACTIVEMQ_URL); // Set asynchronous sending activeMQConnectionFactory.setUseAsyncSend(true); Connection connection = activeMQConnectionFactory.createConnection(); connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = session.createQueue(QUEUE_NAME); // Implementing callbacks using ActiveMQMessageProducer ActiveMQMessageProducer activeMQMessageProducer = (ActiveMQMessageProducer)session.createProducer(queue); TextMessage textMessage = null; for (int i = 1; i <= 3; i++) { textMessage = session.createTextMessage("message=" + i); // Set message id textMessage.setJMSMessageID(IdUtil.fastSimpleUUID() + "-callback"); String msgId = textMessage.getJMSMessageID(); // Implement asynchronous callback to confirm that the message is sent successfully activeMQMessageProducer.send(textMessage, new AsyncCallback() { @Override public void onSuccess() { System.out.println(msgId + " success"); } @Override public void onException(JMSException e) { System.out.println(msgId + " error"); } }); } activeMQMessageProducer.close(); session.close(); connection.close(); System.out.println(" **** Message sent to MQ complete **** "); } }