JMS消息可靠机制
即为消息签收确认(自动签收,手动签收)和消息事务
点对点queue(P2P)
ActiveMQ实例(生产者):
public class MsgProducer {
/**
* mq通讯地址
*/
private final static String URL = "tcp://localhost:61616";
/**
* 队列名称
*/
private final static String QUEUENAME = "my_queue";
public static void main(String[] args) throws JMSException {
//1.创建ActiveMQFactory
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
//2.创建连接
Connection connection = factory.createConnection();
// 3.启动连接
connection.start();
// 4.创建Session 不开启事务,自动签收模式 Session.CLIENT_ACKNOWLEDGE 为手动签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 5.创建一个目标
Queue queue = session.createQueue(QUEUENAME);
// 6.创建生产者
MessageProducer producer = session.createProducer(queue);
// 设置消息持久化 PERSISTENT
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
for (int i = 1; i <= 10; i++){
//"发送者发送第"+i+"条消息~~~~"
User user = new User(i,"suguisen"+i);
ObjectMessage objectMessage = session.createObjectMessage(user);
producer.send(objectMessage);
System.out.println("发送者已成功发送第"+i+"条消息~~~~");
}
// 9.关闭连接
connection.close();
}
}
ActiveMQ实例(消费者):
public class MsgConsumer {
/**
* mq通讯地址
*/
private final static String URL = "tcp://localhost:61616";
/**
* 队列名称
*/
private final static String QUEUENAME = "my_queue";
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
return 1;
};
};
public static void main(String[] args) throws JMSException {
System.out.println("消费者001");
//1.创建ActiveMQFactory
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
//2.创建连接
Connection connection = factory.createConnection();
// 3.启动连接
connection.start();
// 4.创建Session 不开启事务,自动签收模式
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// 5.创建一个目标
Queue queue = session.createQueue(QUEUENAME);
// 6.创建消费者
MessageConsumer consumer = session.createConsumer(queue);
//监听
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
if(message instanceof ObjectMessage){
ObjectMessage objMsg = (ObjectMessage) message;
System.out.println("第"+threadLocal.get()+":"+objMsg);
try {
System.out.println(objMsg.getObject()+"----"+((User)objMsg.getObject()).getUserName());
System.out.println();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
threadLocal.set(threadLocal.get()+1);
}
});
}
}
实体类:
public class User implements Serializable {
private Integer id;
private String userName;
public User(Integer id, String userName) {
super();
this.id = id;
this.userName = userName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
发布/订阅topic
根据队列点对点 只需改:
Topic topic = session.createTopic(TOPICNAME);
Springboot 整合ActiveMQ
点对点队列queue(默认开启队列)
application.yml
spring:
activemq:
###MQ连接通讯地址
broker-url: tcp://127.0.0.1:61616
###账号
user: admin
###密码
password: admin
###自定义队列
my_queue: springboot-queue
server:
port: 8082
QueueConfig配置类,且队列注入bean
将队列注入springboot容器中,其中:
@Configuration 和 @Component 区别
@Configuration
中所有带 @Bean
注解的方法都会被动态代理,@Autowired 获取的是同一个实例
@
Component 中所有带 @Bean
注解的方法被代理后,@Autowired 获取的是不同的实例 ,但是也可以实现同一个实例。
@Configuration
public class QueueConfig {
@Value("${queue}")
private String queue;
@Bean
public Queue queue() {
return new ActiveMQQueue(queue);
}
}
生产者:
@Component
@EnableScheduling
public class Producer {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Queue queue;
@Scheduled(fixedDelay = 5000)
public void send() {
System.out.println(queue+"发送测试消息队列" + System.currentTimeMillis());
jmsMessagingTemplate.convertAndSend(queue, "测试消息队列" + System.currentTimeMillis());
}
}
消费者:
@Component
public class Consumer {
@JmsListener(destination = "${queue}")
public void receive(String msg) {
System.out.println("监听器收到msg:" + msg);
}
}
启动类:
@SpringBootApplication
public class appActiveMQ {
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(appActiveMQ.class, args);
}
}
主题topic
主题:消费者需要开启发布订阅
#### 开启发布订阅
jms:
pub-sub-domain: true
serializable
一个类只有实现了serializable才是可以序列化的,通俗的讲实现了serializable接口后我们将可以把这个类,在网络上进行发送,或者将这个类存入到硬盘,序列化的目的就是保存一个对象。