三木之消息中间件ActiveMQ

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 threadLocal = new ThreadLocal(){
		@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接口后我们将可以把这个类,在网络上进行发送,或者将这个类存入到硬盘,序列化的目的就是保存一个对象。

 

 

你可能感兴趣的:(分布式消息中间件,分布式消息中间件)