消息中间件有很多,常见的比如redis、ActivitiMq、rabbitmq、还有就是阿里的RocketMQ,今天我们主要是尝试一波ActivitiMq,老铁,上车啦!!!
一、入门
首先下载activitimq,官网在这里->http://activemq.apache.org/,选择自己喜欢的版本(楼主用的是5.7.0),解压就可以用啦,
打开解压缩后的文件,点击activemq.bat,浏览器输入->http://localhost:8161/admin,就可以看到你期待已久的界面了,如果需要密码,默认的用户名和密码是admin,如果你想修改密码,跟我来->apache-activemq-5.7.0\conf\jetty.xml,修改<property name="authenticate" value="true" />,然后去->apache-activemq-5.7.0\conf\jetty-realm.properties,修改用户名和密码,默认是这样的admin: admin, admin(用户名:密码:角色),恭喜入门。哇哇哇!!!
二、使用场景
说个大概吧,一般比如说购物网站高峰期的时候,用户提交订单后,先把订单信息放入消息队列中,避免了去数据库存取,因为放入内存中执行速度远远大过磁盘,处理订单模块去消息队列中处理成功后返回。好了,其他的自己摸索吧!!!
三、具体使用
环境:eclipse、maven
以下代码只考虑了点对点的发送消息,如果是订阅模式,那它的实现是Topic, session.createTopic("")
直接贴代码
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-broker -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-client -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
<version>5.14.0</version>
</dependency>
消息发送端:
public static void main(String[] args) {
//连接工厂
ConnectionFactory connectionFactory;
//JMS 客户端到JMS Provider 的连接
Connection connection;
//一个发送或接收消息的线程
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// MessageProducer:消息发送者
MessageProducer messageProducer;
connectionFactory=new
ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection=connectionFactory.createConnection();
connection.start();
session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//这里会自动创建Queue
destination=session.createQueue("secondqueue");
messageProducer=session.createProducer(destination);
//设置生产者的模式,有两种可选
//DeliveryMode.PERSISTENT 当activemq关闭的时候,队列数据将会被保存
//DeliveryMode.NON_PERSISTENT 当activemq关闭的时候,队列里面的数据将会被清空
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
//设置消息过期时间
messageProducer.setTimeToLive(10000);
sendMessage(session, messageProducer);
// session.commit();
session.close();
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void sendMessage(Session session,MessageProducer producer){
TextMessage message;
try {
for(int i=0;i<10;i++){
message = session.createTextMessage("测试发送的消息"+i);
producer.send(message);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (JMSException e) {
e.printStackTrace();
}
}
消息接收端:
public static void main(String[] args) {
//连接工厂
ConnectionFactory connectionFactory;
//JMS 客户端到JMS Provider 的连接
Connection connection;
//一个发送或接收消息的线程
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// MessageProducer:消息消费者
MessageConsumer consumer;
connectionFactory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection=connectionFactory.createConnection();
connection.start();
session=connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
destination=session.createQueue("firstqueue");
consumer=session.createConsumer(destination);
while(true){
TextMessage message=(TextMessage) consumer.receive();
System.out.println(message.getText());
message.acknowledge();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
接收端可以使用主动监听消息
public static void main(String[] args) {
//连接工厂
ConnectionFactory connectionFactory;
//JMS 客户端到JMS Provider 的连接
Connection connection;
//一个发送或接收消息的线程
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// MessageProducer:消息消费者
MessageConsumer consumer;
connectionFactory=new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
connection=connectionFactory.createConnection();
connection.start();
session=connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
destination=session.createQueue("firstqueue");
consumer=session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
//变了这个地方,但是有一个问题,当我们程序很累很累的时候,如果还自动去获取消息,会不会太不人道了
//因此我们可以判断服务器不累的时候再去获取消息,下面一句代码的意思是超过定义的时间,就不再继续获取
//TextMessage message=(TextMessage) consumer.receive(1000);
public void onMessage(Message message) {
try {
String text = ((TextMessage)message).getText();
System.out.println(text);
} catch (JMSException e) {
e.printStackTrace();
}
try {
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
四、注意
1、
1.connection.createSession(
false
, Session.
AUTO_ACKNOWLEDGE
);
2.connection.createSession(
false
, Session.
CLIENT_ACKNOWLEDGE
);
第一个参数代表是否缓存,如果第一个参数为true,那么第二个参数无效,
AUTO_ACKNOWLEDGE 意思是消息发送给接收端后,就自动确认,不管接收端是否收到
CLIENT_ACKNOWLEDGE 这个只能用在接收端,表示接收端是否成功接收到消息,成功接收到后消息离别就会自动删除这条消息,注意,你必须要提交确认message.acknowledge();
2、message = session.createTextMessage("测试发送的消息"+i);
createTextMessage:字符串形式的消息,还可以发送Map,以及对象,这里很简单,主要是不想打架错过这个地方。
这么多,你都看到我了,果然是真爱啊!!!!