消息中间件
MOM(message Orient middleware)
用途和特点:
- 将数据从一个应用传送到另外一个应用,或者从软件的一个模块传到另外一个模块
- 负责建立网络通道,进行数据的可靠传送
- 保证数据不重发,不丢失(JMS点对点)
- 能够实现跨平台操作,为不同操作系统上的不同软件实现服务
MQ(Message Queue)
简单理解就是一个消息的接受和转发装置 ,可用于消息推送
ActiveMQ
Apache ActiveMQ ™ is the most popular and powerful open source messaging and Integration Patterns server.
Apache ActiveMQ is fast, supports many Cross Language Clients and Protocols, comes with easy to use Enterprise Integration Patterns and many advanced features while fully supporting JMS 1.1 and J2EE 1.4.
Apache ActiveMQ是一款最受欢迎的,强力开源的消息集成模式服务器.Apache ActiveMQ非常快速,支持多种跨语言客户端和协议,越来越简单使用在企业集成服务中,并且充分支持了JMS1.1和J2EE1.4的许多高级特性.
特性:
- 支持来自Java,C,C++,C#,Ruby,Perl,Python,PHP的各种跨语言和协议.
- 充分支持JMS客户端和Message Broker中的企业集成模式(Enterprise Integration Patterns)
- 支持很多高级特性,比如:消息组(Message Groups),虚拟目标(Virtual Destinations),通配符(WildCards),综合目标(Composite Destinations).
- 完全支持JMS1.1和J2EE1.4,支持 瞬态(transient ),持久化(persistent),事务(transactional)和XA messageing(一种传输协议)
- 由于spring的支持,所以ActiveMQ更容易嵌入到spring的应用中去,并且被springXMl配置机制配置
- 在流行的J2EE服务器(TomEE,Geronimo,JBoss,Glassfish,和WebLogic)里进行测试
- 支持可插播的传输协议,如:in-VM,TCP,SSL,NIO,UDP,multicast,JGroup和JXTA transports
- 支持使用JDBC和高性能日志的快速持久化
- 专为高性能集群,client-server,基于对等的通信而设计.
- REST API为消息传递提供 对未知技术的,语言中立的,基于web的API
- 异步支持使用纯净的DHTML的WEB浏览器的Web流支持,允许Web浏览器称为消息传递结构的一部分
- 因为CXF和Axis的支持,所以ActiveMQ可以轻松的放入这些Web服务栈中来提供可靠的消息传递
- 可以当做内存中的JMS提供者,JMS单元测试理性的选择
什么情况下使用ActiveMQ?
多个项目之间集成(1) 跨平台(2) 多语言(3) 多项目
降低系统间模块的耦合度,解耦(1) 软件扩展性系统前后端隔离(1) 前后端隔离,屏蔽高安全区
使用
maven仓库下载jar包: activemq-all-5.10.0.jar
activemq-all-5.10.0.jar
代码如下,注意创建队列的类型是topic还是queue
import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; /** * @author Dougest * @version 创建时间:2018年5月16日 下午5:21:06 * @describe : * */ public class JMSProducer { //默认连接用户名 private static final String USERNAME = ActiveMQConnection.DEFAULT_USER; //默认连接密码 private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD; //默认连接地址 private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL; //发送的消息数量 private static final int SENDNUM = 10; public static final String QUEUE_NAME = "yly.queue"; public static final String TOPIC_NAME = "yly.topic"; public static void main(String[] args) { //连接工厂 ConnectionFactory connectionFactory; //连接 Connection connection = null; //会话 接受或者发送消息的线程 Session session; //消息的目的地 Destination destination; //消息生产者 MessageProducer messageProducer; //实例化连接工厂 connectionFactory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL); try { //通过连接工厂获取连接 connection = connectionFactory.createConnection(); //启动连接 connection.start(); //创建session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); // destination = session.createQueue(QUEUE_NAME); // destination = session.createTopic(TOPIC_NAME); //创建消息生产者 messageProducer = session.createProducer(destination); //发送消息 sendMessage(session, messageProducer); session.commit(); } catch (Exception e) { e.printStackTrace(); }finally{ if(connection != null){ try { connection.close(); } catch (JMSException e) { e.printStackTrace(); } } } } /** * 发送消息 * @param session * @param messageProducer 消息生产者 * @throws Exception */ public static void sendMessage(Session session,MessageProducer messageProducer) throws Exception{ for (int i = 0; i < JMSProducer.SENDNUM; i++) { //创建一条文本消息 TextMessage message = session.createTextMessage("ActiveMQ 发送消息" +i); System.out.println("发送消息:Activemq 发送消息" + i); //通过消息生产者发出消息 messageProducer.send(message); } } }
消费者:
import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; /** * @author Dougest * @version 创建时间:2018年5月16日 下午5:21:52 * @describe : * 消费者 */ public class JMSConsumer { private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认连接用户名 private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认连接密码 private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址 public static final String QUEUE_NAME = "yly.queue"; static { } public static void main(String[] args) { ConnectionFactory connectionFactory;//连接工厂 Connection connection = null;//连接 Session session;//会话 接受或者发送消息的线程 Destination destination;//消息的目的地 MessageConsumer messageConsumer;//消息的消费者 //实例化连接工厂 connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL); try { //通过连接工厂获取连接 connection = connectionFactory.createConnection(); //启动连接 connection.start(); //创建session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); //创建一个连接HelloWorld的消息队列 destination = session.createQueue(QUEUE_NAME); //创建消息消费者 messageConsumer = session.createConsumer(destination); while (true) { TextMessage textMessage = (TextMessage) messageConsumer.receive(100000); if(textMessage != null){ System.out.println("收到的消息:" + textMessage.getText()); }else { break; } } } catch (JMSException e) { e.printStackTrace(); } } }
先启动生产者,结果如下:
发送消息:Activemq 发送消息0
发送消息:Activemq 发送消息1
发送消息:Activemq 发送消息2
发送消息:Activemq 发送消息3
发送消息:Activemq 发送消息4
发送消息:Activemq 发送消息5
发送消息:Activemq 发送消息6
发送消息:Activemq 发送消息7
发送消息:Activemq 发送消息8
发送消息:Activemq 发送消息9
再启动消费者
收到的消息:ActiveMQ 发送消息0
收到的消息:ActiveMQ 发送消息1
收到的消息:ActiveMQ 发送消息2
收到的消息:ActiveMQ 发送消息3
收到的消息:ActiveMQ 发送消息4
收到的消息:ActiveMQ 发送消息5
收到的消息:ActiveMQ 发送消息6
收到的消息:ActiveMQ 发送消息7
收到的消息:ActiveMQ 发送消息8
收到的消息:ActiveMQ 发送消息9
密码账号密码:admin/admin