- 常见的消息队列有哪些?
目前主流的消息队列有以下ActiveMQ RabbitMQ KafKa ZeroMQ MetaMQ RocketMQ
- 用ActiveMQ举例,用java实现点对点(P2P)的流程是怎样的
首先是生产者需要new一个ActiveMQConnectionFactory,用这个factory来创建connection,然后通过connection创建session,而通过session创建Queue,生产者和TextMessage,最后通过生产者send到队列中去
//创建ConnectionFactory 用户名密码都是null
ConnectionFactory factory =new ActiveMQConnectionFactory(null,null,"tcp://localhost:61616");
//创建Connectin
Connection connection=factory.createConnection();
//创建Session 通过Connection创建的,不开启事务
Session session =connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//创建Destination(Queue Topic) 由Session创建出消息队列
Queue queue =session.createQueue("hello");
//创建producer生产者
MessageProducer producer = session.createProducer(queue);
//由session创建Message
TextMessage textMessage = session.createTextMessage("第一条MQ消息'");
//使用Producer发送消息
producer.send(textMessage);
producer.close();
session.close();
connection.close();
System.out.println("发送完成");
}
而消费者这边,前面不变也是factory->connection->session,session也是需要创建Queue和Consumer–>开一个线程或者监听器去receive(),Consurmer这边的代码:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(null, null, "tcp://localhost:61616");
// connection
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//Session创建消息队列 --和生产者那边一模一样 否则会创建一个新的队列
Queue queue = session.createQueue("hello");
MessageConsumer consumer = session.createConsumer(queue);
while(true){
Message receive = consumer.receive();
if(receive!=null){
TextMessage m =(TextMessage)receive;
System.out.println(m.getText().toString());
TimeUnit.SECONDS.sleep(1);
}
}
这就完成了点对点的消息传递
- 以ActiveMQ为例,topic的消息传递的流程是怎样的呢?
流程也是ActiveMQConnectionFactory去创建Connection,Connection创建Session,Session创建Topic,生产者,和MapMessage,最后由生产者send到消息队列中,代码如下:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(null, null, "tcp://localhost:61616");
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
//创建了一个话题
Topic topic = session.createTopic("topic");
//创建生产者
MessageProducer producer = session.createProducer(topic);
MapMessage mapMessage =session.createMapMessage();
mapMessage.setString("name","zs");
mapMessage.setInt("age",22);
producer.send(mapMessage);
producer.close();
session.close();
connection.close();
System.out.println("消息发送完成");
}
消费者大相径庭factory->connection->session->consumer,topic以及Listener
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(null, null, "tcp://localhost:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Topic topic = session.createTopic("topic");
MessageConsumer consumer = session.createConsumer(topic);
consumer.setMessageListener(message -> {
if(message!=null && message instanceof MapMessage){
MapMessage m=(MapMessage)message;
try {
System.out.println(m.getInt("age")+m.getString("name"));
m.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
- SpringMVC和SpringBoot如何整合ActiveMQ
使用JmsTemplate,ActiveMQFactory,CachingConnectionFactory,以及JmsTemplate,以SpringBoot为例,说说流程
@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory(){
return new ActiveMQConnectionFactory(null,null,"tcp://localhost:61616");
}
@Bean
/*Spring用于管理真正的ConnectionFactory的ConnectionFactory*/
public CachingConnectionFactory connectionFactory(){
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setTargetConnectionFactory(this.activeMQConnectionFactory());
cachingConnectionFactory.setSessionCacheSize(30);
return cachingConnectionFactory;
}
@Bean
/*Spring提供的JMS工具类,它可以进行消息发送、接收等*/
public JmsTemplate jmsTemplate(){
JmsTemplate jmsTemplate = new JmsTemplate();
//传入工厂
jmsTemplate.setConnectionFactory(this.connectionFactory());
//开启服务质量控制
jmsTemplate.setExplicitQosEnabled(true);
//持久化------生产者
jmsTemplate.setDeliveryMode(DeliveryMode.PERSISTENT);
//客户端签收消息
jmsTemplate.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return jmsTemplate;
}
Service调用并发布信息
//false为默认 发送Queue true发Topic
jmsTemplate.setPubSubDomain(true);
jmsTemplate.send("email", session -> {
return session.createTextMessage(JSONObject.toJSONString(email));
});
消费者:以下部署,注意是发布者是Queue还是Topic,对应好,消费者需要做的事情:ActiveMQConnectionFactory->CacheConnectionFactory->队列/订阅->LinstenerContainer
以下我用SpringMVC部署去写 相当于把SpringBoot和SpringMVC都写了一遍吧
<bean id="mqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
c:userName=""
c:password=""
c:brokerURL="tcp://localhost:61616"/>
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"
c:targetConnectionFactory-ref="mqConnectionFactory"
p:sessionCacheSize="30"/>
<bean id="emailTopic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg name="name" value="email" />
</bean>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<!--CachingConnectionFactory-->
<property name="connectionFactory" ref="connectionFactory"/>
<!--队列-->
<property name="destination" ref="emailTopic"/>
<!--自己写的监听器-->
<property name="messageListener" ref="emailMsgListener"/>
<!--签收方式 2表示手动签收 1表示自动签收-->
<property name="sessionAcknowledgeMode" value="2"/>
</bean>
这样就配置完毕了;最后只需要一个配置一个监听器用onMessage方法拿值就可以了
最后textMessage.acknowledge();//签收消息