客户端
package com.zhuguang.jack.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class QueueConsumer {
public static void main(String[] args) {
String username = "system";
String password = "manager";
String brokerURL = "failover://tcp://192.168.1.10:61616";
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Destination destination = null;
MessageProducer messageProducer = null;
connectionFactory = new ActiveMQConnectionFactory(username, password, brokerURL);
try {
connection = connectionFactory.createConnection();
connection.start();
/*
* 第一个参数:是否支持事务,如果是true的话,第二个参数就会忽略
*
* 第二个参数:消息确认机制
*
* Session.AUTO_ACKNOWLEDGE:自动确认消息,consumer.receive只要有返回就确认成功处理消息,哪怕处理消息
* 出现异常也是给了一个成功的应答
*
* Session.CLIENT_ACKNOWLEDGE:客户端接收消息后,必须调用ackknowledge方法手动确认,手动确认才会删除
*
* Session.DUPS_OK_ACKNOWLEDGE:批量确认消息
* DUPS_OK_ACKNOWLEDGE = AUTO_ACKNOWLEDGE + 延迟
*
*
* 1、如果生产者是事务消息,那么消费者也要保证是事务消息
*
* */
session = connection.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
destination = session.createQueue("zgqueue");
MessageConsumer consumer = session.createConsumer(destination);
final Session finalSession = session;
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
if (message instanceof TextMessage) {
textMessage((TextMessage)message);
} else if(message instanceof ObjectMessage) {
objectMessage((ObjectMessage)message);
} else if(message instanceof BytesMessage) {
bytesMessage((BytesMessage)message, finalSession);
}
}
});
/*while (true) {
try {
// receive 方式是阻塞式的,想比于自动确认消息,处理消息慢, 但是这里可以根据计算机的性能 进行一些操作,而自动确认消息是不管计算机性能的 直接是无脑接收
TextMessage textMessage = (TextMessage) consumer.receive(100000);
if (textMessage != null) {
System.out.println("成功接收消息:" + textMessage.getText());
} else {
break;
}
textMessage.acknowledge();
// int i = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
*//*
* ActiveMQ.DLQ 如果rollback成功,会把消息存储在DLQ队列
* 1、过期消息
* 2、处理失败消息
* 3、回滚消息
*
* *//*
session.rollback();
}
*//* try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//当业务逻辑处理完后,手动确认,挨个确认,比较好资源
textMessage.acknowledge();*//*
}*/
} catch (JMSException e) {
e.printStackTrace();
}
}
private static void textMessage(TextMessage textMessage) {
try {
System.out.println("成功接收消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
private static void objectMessage(ObjectMessage objectMessage) {
try {
User user = (User) objectMessage.getObject();
System.out.println(user.getUsername()+":" + user.getPassword());
} catch (JMSException e) {
e.printStackTrace();
}
}
private static void bytesMessage(BytesMessage bytesMessage,Session session) {
FileOutputStream os = null;
try {
String filename = bytesMessage.getStringProperty("filename");
os = new FileOutputStream("F:" + File.separator + filename);
byte[] bytes = new byte[1024];
int len = 0;
while((len = bytesMessage.readBytes(bytes))!= -1) {
os.write(bytes,0,len);
}
System.out.println("文件保存成功!!");
//获取回执消息
Destination jmsReplyTo = bytesMessage.getJMSReplyTo();
TextMessage textMessage = session.createTextMessage("文件处理成功回执消息:" + filename);
//此处变成了生产者
MessageProducer producer = session.createProducer(jmsReplyTo);
producer.send(textMessage);
} catch (JMSException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
生产端
package com.zhuguang.jack.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class QueueProducer {
public static void main(String[] args) {
String username = "system";
String password = "manager";
String brokerURL = "failover://tcp://192.168.1.10:61616";
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Destination destination = null;
MessageProducer messageProducer = null;
connectionFactory = new ActiveMQConnectionFactory(username, password, brokerURL);
try {
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
Queue zgqueue = session.createQueue("zgqueue");
MessageProducer producer = session.createProducer(zgqueue);
//默认是一个持久化的消息存储机制
// producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
textMessage(session, producer);
// objectMessage(session, producer);
// byteMessage(session, producer);
// session.commit();
} catch (JMSException e) {
e.printStackTrace();
try {
session.rollback();
} catch (JMSException e1) {
e1.printStackTrace();
}
}
}
private static void textMessage(Session session, MessageProducer producer) {
try {
TextMessage textMessage = session.createTextMessage();
for (int i = 0; i < 10; i++) {
textMessage.setText("生产消息测试 : " + i);
producer.send(textMessage);
System.out.println("发送成功:" + textMessage.getText());
}
} catch (JMSException e) {
e.printStackTrace();
}
}
private static void objectMessage(Session session, MessageProducer producer) {
try {
ObjectMessage objectMessage = session.createObjectMessage();
// objectMessage.setJMSReplyTo();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setUsername("jack" + i);
user.setPassword("123" + i);
objectMessage.setObject(user);
producer.send(objectMessage);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
private static void byteMessage(Session session, MessageProducer producer) {
FileInputStream is = null;
try {
BytesMessage bytesMessage = session.createBytesMessage();
replyMessage(session, "bytemsg_reply_queue", bytesMessage);
bytesMessage.setStringProperty("filename", "my.ini");
File file = new File("D:" + File.separator + "software" + File.separator + "my.ini");
is = new FileInputStream(file);
byte[] buffer = new byte[is.available()];
is.read(buffer);
bytesMessage.writeBytes(buffer);
producer.send(bytesMessage);
System.out.println("send to broker!!");
} catch (JMSException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void streamMessage(Session session,MessageProducer producer) {
try {
StreamMessage streamMessage = session.createStreamMessage();
} catch (JMSException e) {
e.printStackTrace();
}
}
private static void replyMessage(Session session, String queuename, Message message) {
try {
Queue queue = session.createQueue(queuename);
message.setJMSReplyTo(queue);
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
if (message != null && message instanceof TextMessage) {
try {
System.out.println("reply message : " + ((TextMessage) message).getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
}
pom
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
如果服务端 发的事务消息, 客户端配置的非事务消息, 则客户端接不到。
如果服务端发的是非事务消息,客户端用事务消息去接, 发现 此消息一直存在,可以被多次消费, 就算调用 acknowledge()方法也不行