Apache Activemq-JMS了解+mq指定JDK
了解 apache mq
今天突然被老大叫去 ,安排了部署环境。结果对mq 不太了解。随手记 ,了解mq
简介
Apache ActiveMQ是 基于消息的通讯中间件。
支持JMS的两种消息模式。是JMS的一个实现
JMS:
1.Java消息服务:Java Message Service 应用程序接口,
Java平台中关于面向*消息中间性(MOM)*的API,用于在两个程序之间,或者 分布式系统中发送消息,进行异步通信。
简单理解:两个应用程序之间通信,使用JMS服务,用作中间的转发。可以解除两个程序之间的耦合。
2.优势:
- 异步:异步的消息服务,客户端获取消息的时候,不需要主动发送请求,消息会自动发送给可用的客户端
- 可靠:保证只会消息递送一次。避免了重复创建消息问题
3.两种通信模式:
(1):Point-to-Point Messaging Domain 点对点
(2):Publish/Subscribr Messaging Domain 发布/订阅模式
这两种消息发送模型 相互独立。
(1)点对点通信模型:
-
发送方,消息队列,接收方
-
每个消息都被发送到一个特定队列,接收者从队列中获取消息。队列保留着消息,知道他们被消费胡哦超时。
举例:QQ通信,A下线了,B给A发送了消息,B发送完消息就下线了。A上线的时候 依旧可以接收到消息。(朋友给的举例,不知是否准确,但是很贴合) -
每个消息只要一个消费者。
发送者和接收者没有时间的约束,发送者发送完消息后 不管接收者有没有接收到消息都不会影响发送者发送消息到消息队列中。
发送方不管是否在发送消息,接收方都可以从消息队列中取到消息。
接收方在接受完消息之后,需要向消息队列应答成功
(2)发布/订阅通信模式: -
发布者发布一个消息,通过topic(主题)传递给所有的客户端。发布者和订阅者都是匿名的,可动态的发布和订阅Topic。Topic主要用于保存和传递消息,且会一直保存消息知道消息被传递给客户端。
-
一个消息可以传递个多个订阅者,可以有多个接收方
发布者和订阅者具有时间约束,针对某个Topic的订阅者,必须创建一个订阅者之后,才能消费发布者的消息,且为了消费消息,订阅者必须保持运行状态 -
为缓和时间相关性,JMS允许订阅者创建一个可持久化的订阅,这样即使订阅者没有被激活(运行),它也能接收到发布者的消息。
4.JMS接受消息
JMS中,消息的产生和消息是异步的。看通过两种方法来消费消息
(1)同步:
同步消费信息模式中,订阅者/接收方 调用recieve()方法接收消息,线程会阻塞知道消息到达或者指定时间后消息仍未到达
(2) 异步:
异步,订阅者/接收方需要注册一个消息监听者,类似于事件监听器,只要消息到达,JMS服务提供者会通过调用监听器onMessage()递送消息
5.JMS编程模型
- 管理对象Administered objects --连接工厂Connection Factories 和目的地Destination
连接对象Connections
会话Sessions
消息产生者Message Producers
消息消费者Message Consumers
消息监听者 Message Listeners
1-6大体看了一下,未仔细看,后续有时间再翻看吧
(1)、Connection Factories
创建Connection对象的工厂,针对两种不同的jms消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。客户端使用一个连接工厂对象连接到JMS服务提供者,它创建了JMS服务提供者和客户端之间的连接。JMS客户端(如发送者或接受者)会在JNDI名字空间中搜索并获取该连接。使用该连接,客户端能够与目的地通讯,往队列或话题发送/接收消息。
QueueConnectionFactory queueConnFactory = (QueueConnectionFactory) initialCtx.lookup ("primaryQCF");
Queue purchaseQueue = (Queue) initialCtx.lookup ("Purchase_Queue");
Queue returnQueue = (Queue) initialCtx.lookup ("Return_Queue");
(2)、Destination
目的地指明消息被发送的目的地以及客户端接收消息的来源。JMS使用两种目的地,队列和话题。创建一个队列Session:
QueueSession ses = con.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); //get the Queue object
Queue t = (Queue) ctx.lookup ("myQueue"); //create QueueReceiver
QueueReceiver receiver = ses.createReceiver(t);
(3)、Connection
Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种类型:QueueConnection和TopicConnection。
连接对象封装了与JMS提供者之间的虚拟连接,如果我们有一个ConnectionFactory对象,可以使用它来创建一个连接。
Connection connection = connectionFactory.createConnection();
4)、Session
Session 是我们对消息进行操作的接口,可以通过session创建生产者、消费者、消息等。Session 提供了事务的功能,如果需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。
我们可以在连接创建完成之后创建session:
第一个参数是是否支持事务,第二个是事务的类型
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
(5)、Producter
消息生产者由Session创建,用于往目的地发送消息。生产者实现MessageProducer接口,我们可以为目的地、队列或话题创建生产者;
MessageProducer producer = session.createProducer(dest);
MessageProducer producer = session.createProducer(queue);
MessageProducer producer = session.createProducer(topic);
6)、Consumer
消息消费者由Session创建,用于接收被发送到Destination的消息。
MessageConsumer consumer = session.createConsumer(dest);
MessageConsumer consumer = session.createConsumer(queue);
MessageConsumer consumer = session.createConsumer(topic);
(7)、MessageListener
消息监听器。如果注册了消息监听器,一旦消息到达,将自动调用监听器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一种MessageListener。
6.用的
应用程序A将Message发送到服务器上,然后应用程序B从服务器中接收A发来的消息,
提供了消息灵活性,松散耦合,异步性
ActiveMQ 环境配置、安装
介绍
- 需要JRE1.7以后的版本,并配置JAVA_HOME 环境变量
- 官网应该可以下载吧
- 解压即可使用,解压后的目录结构:
bin:启动脚本
conf:配置文件
data:日志文件和消息持久化存储位置
lib:分功能的jar包
activemq-all-X.XX.X.jar:全功能jar包
运行
- 启动cmd,cd到“<解压目录>\bin”目录下。执行命令activemq.bat start。或者可以将该目录加入环境变量,以后启动activemq服务时就不用先cd到该目录下了。
- 出现类似Apache ActiveMQ 5.11.1 (localhost, ID:ntbk11111-50816-1428933306116-0:1) started | org.apache.activemq.broker.BrokerService | main这样的输出,说明ActiveMQ启动成功。输出日志也可以在data目录下的文件activemq.log中查看。
- 启动前要确保这几个端口未被占用:61616,5672,61613,1883,61614,8161。
- 启动成功后不要关掉cmd窗口
- 浏览器输入URLhttp://127.0.0.1:8161/admin,登录名和密码默认都是admin。可以在conf目录下的文件jetty-realm.properties中修改登录名和密码。
- 直接关掉cmd窗口就可以停止ActiveMQ服务
指定运行JDK(引用各位前辈的例子)
- 配置bin 下 env文件,这只JAVA_HOME
# Specify the location of your java installation using JAVA_HOME, or specify the$
# path to the "java" binary using JAVACMD$
# (set JAVACMD to "auto" for automatic detection)$
JAVA_HOME="/why/java/jdk1.8.0_131"
JAVACMD="auto"
再次运行bin/activemq start
运行成功
访问http://host:8161/admin/queues.jsp
- 修改apache-activemq-5.14.5/bin/linux-x86-64/wrapper.conf 中的wrapper.java.command=java
# Java Application
#wrapper.java.command=java
wrapper.java.command=/why/java/jdk1.8.0_131/bin/java
重启查看data/wrapper.log 修改生效
bin目录下的activemq.bat文件启动ActiveMQ的,所有需要修改该文件。
if "%JAVA_HOME%" == "" goto noJavaHome
if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe
goto runAnt
这个位置就是判断JAVA_HOME变量的位置。所有我在这个之前添加如下语句:
set JAVA_HOME=C:\Program Files\Java\jdk1.5.0_22
代码示例(待尝试)
32位和64位JDK安装
服务器上 本身是装了32位的
我要安装64位的 并指定给mq
CLASSPATH:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\tools.jar;%JAVA_HOME%\lib\oracle_common.jar;
JAVA_HOME:D:\Java\jdk-7-windows-i586\Java\jdk1.7.0
JAVA_HOME64:D:\Java\jdk1.7.0_60
path:
%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
%JAVA_HOME64%\bin;%JAVA_HOME64%\jre\bin;
(引用大佬分享:)
path中是从前往后依次匹配的,上面两个,哪个在前,就先识别哪个,另一个就不能用了,我电脑上装了两个eclipse32位和64位和jdk32位和64位,如果32位的在path中配置在前,则只能打开32位的eclipse,64位的会
弹出“Failed to load the JNI shared library jvm.dll”
同理,64位的在前则只能打开64位的eclipse,32位的报异常