ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
主要特点:
1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
2. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
3. 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
4. 通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上
5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
6. 支持通过JDBC和journal提供高速的消息持久化
7. 从设计上保证了高性能的集群,客户端-服务器,点对点
8. 支持Ajax
9. 支持与Axis的整合
10. 可以很容易得调用内嵌JMS provider,进行测试
1. ActiveMQ 在linux下的安装和运行
(1) 下载ActiveMQ http://activemq.apache.org/download.html
linux下版本 http://www.apache.org/dyn/closer.cgi?path=%2Factivemq%2Fapache-activemq%2F5.5.0%2Fapache-activemq-5.5.0-bin.tar.gz
wget http://labs.renren.com/apache-mirror//activemq/apache-activemq/5.5.0/apache-activemq-5.5.0-bin.tar.gz
(2) 解压 tar zxvf apache-activemq-5.5.0-bin.tar.gz
(3) 运行 apache-activemq-5.5.0/bin/activemq start 默认端口是61616 可以用 netstat -an|grep 61616 来查看
(4) 修改端口 在 apache-activemq-5.5.0/conf/activemq.xml 找到
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/> 然后把 61616 该为你想要的端口
(5) 设置用户名和密码,来验证客户端的连接
在 apache-activemq-5.5.0/conf/credentials.properties 文件中,修改用户名和密码
activemq.username=system
activemq.password=manager
guest.password=password
(6) 停止 activemq ,执行 apache-activemq-5.5.0/bin/activemq stop
2. 使用java 来调用
(1) 先要获得ConnectionFactory
private static ConnectionFactory connectionFactory; /** * 获得连接工厂 * */ public static ConnectionFactory getJMSConnectionFactory() { if(connectionFactory == null){ ConfigModel configModel = ConfigFactory.getConfigModel(); //可以设置设定好的用户名和密码 connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, "tcp://192.168.0.3:61616"); } return connectionFactory; }
(2) 发送消息(一个邮件模型),这个模型会保存起来,所以不是发送模型是不费时间的。
/** * 发送一个邮件对象 * */ public static void sendEmailOperationModel(EmailModel emailModel){ ConnectionFactory connFactory = getJMSConnectionFactory(); try { //JMS 客户端到JMS Provider 的连接 Connection connection = connFactory.createConnection(); connection.start(); // Session: 一个发送或接收消息的线程 Session session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE); // Destination :消息的目的地;消息发送给谁. // 获取session注意参数值my-queue是Query的名字 Destination destination = session.createQueue(AppConstants.JMS_QUEUE_NAME_EMAIL); // MessageProducer:消息生产者 MessageProducer producer = session.createProducer(destination); // 设置失效时间 //producer.setTimeToLive(3600 * 1000 * 24 * 2); //设置持久化 //producer.setDeliveryMode(DeliveryMode.PERSISTENT); //发送一条消息 ObjectMessage objectMessage = session.createObjectMessage(emailModel); //通过消息生产者发出消息 producer.send(objectMessage); session.commit(); connection.close(); } catch (Exception e) { e.printStackTrace(); } }
(3) 触发来发送邮件,这个是异步操作,不影响系统性能, 需要在系统启动时启动这个线程来监听消息,然后发邮件
public class MailSendManager extends Thread{ protected final Log log = LogFactory.getLog(MailSendManager.class); public MailSendManager() { } /** * 等待接受操作信息然后发邮件 * */ public static void sendEmail(){ try { //JMS 客户端到JMS Provider 的连接 Connection connection = JMSFactory.getJMSConnectionFactory().createConnection(); connection.start(); // Session: 一个发送或接收消息的线程 Session session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE); // Destination :消息的目的地;消息发送给谁. // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置 Destination destination = session.createQueue(AppConstants.JMS_QUEUE_NAME_EMAIL); MessageConsumer consumer = session.createConsumer(destination); //应用阻塞模式 /*while (true) { Message message = consumer.receive(); if(message instanceof ObjectMessage){ ObjectMessage omsg = (ObjectMessage) message; //EmailModel operationModel = (EmailModel) omsg.getObject(); //发送邮件 //MailSender.sendMail(operationModel); System.out.println("send email ok --------------"); } } */ //应用事件模型 consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { try { if (message instanceof ObjectMessage) { ObjectMessage omsg = (ObjectMessage) message; EmailModel operationModel = (EmailModel) omsg.getObject(); //发送邮件 MailSender.sendMail(operationModel); } } catch (Exception e) { e.printStackTrace(); } } }); //session.close(); //connection.close(); } catch (Exception e) { e.printStackTrace(); } } public void run(){ MailSendManager.sendEmail(); }