JMS消息服务-ActiveMQ
来源:互联网 发布:数据分析 java 编辑:程序博客网 时间:2024/04/28 02:40
JMS消息服务-ActiveMQ
sf2gis@163.com
2015年7月28日
1 JMS消息服务
目标:网络或进程间的消息异步、同步通信、点对点或发布模式通信。将消息的收、发方解耦。
原理:Java提供JMS(Java Message Service)作为消息服务的规范,可以有不同的实现方法。发送方将消息发向JMS服务器,由JMS服务器处理消息后再发送到收取方。
参考:http://my.oschina.net/zmf/blog/368017
方法:开源消息服务软件,ActiveMQ。
2 方法:ActiveMQ服务器
2.1 打开服务器:bin\activemqstart。
注意:有可能出现VM创建错误,这是由于ActiveMQ默认需要1G内存,如果物理内存不足,则创建失败。可能通过释放内存,达到1G再启动。或者修改ActiveMQ的内存配置(推荐)。
启动成功后出现下图所示:access to all MBeans is allowed。
2.2 修改内存配置:activemq.bat。
修改第80行-Xms -Xmx为512m或更少。
参考:http://activemq.apache.org/javalangoutofmemory.html
2.3 关闭服务器:ctrl+C
2.4 打开WEB 控制台:localhost:8161,可以看到控制台和示例程序。
示例程序在webapps-demo/demo中,需要从其中copy到webapps中。
3 方法:消息收发模式:点对点,订阅
由消息服务器管理消息,收发双方独立联系服务器,消息的生命周期由消息服务器管理。
3.1 点对点:单线联系。
双方完全无关,不须维持在线状态。
3.2 订阅:广播。
临时订阅时,订阅者须维持在线状态。
持久订阅时,双方完全无关,不须维持在线状态。
3.3 消息持久化:存储消息,重启后消息依然存在。
可以指定数据库。
参考:http://bbs.paris8.org/viewthread.php?tid=4252
3.4 集群:扩展服务器
可以使用集群服务器扩展性能。
参考:http://blog.evercoding.net/2014/07/17/activemq-note/
4 方法:收发消息
目标:与消息服务器进行消息收发。
原理:收/发方通过与服务器建立连接,然后以session为单位建立单线程消息收/发。
方法:设置服务器地址和类型、编写收发逻辑。
参考:
http://baike.baidu.com/link?url=XaCsMIRVQEhZLTQB2jI1ysPQK0xUCKWaE9UQlFXVbPPKralw6XTFJHv8j6HnbcPMOjZYHFUMR5Ir_P6d2OE28kvtLTBCBLDHuvPyEC_rA0q
4.1 设置服务器:设置服务器的连接地址。
目标:配置mq服务器能够提供服务的IP地址。
方法:修改conf/activemq.xml中<transportConnectors>的连接选项,默认是tcp://0.0.0.0:61616。
具有多种类型的连接,如tcp,udp,http等。
参考:http://activemq.apache.org/configuring-transports.html
示例:添加新的tcp连接服务tcp://0.0.0.0:61618。
<transportConnectors>
<!-- DOS protection, limitconcurrent connections to 1000 and frame size to 100MB -->
<transportConnectorname="openwire"uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="tcp"uri="tcp://0.0.0.0:61618?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="stomp"uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="ws"uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
4.2 建立连接:Connection。
4.2.1配置连接工厂:连接使用ConnectionFactory配置连接服务器,并由其创建连接。使用完成之后要关闭连接服务器和连接。
4.2.2建立连接:使用连接工厂生成一个连接。并使用start()启动连接。
只有启动连接才真正的建立连接。
4.2.3示例
//create connection
ConnectionFactory cf=newActiveMQConnectionFactory("tcp://localhost:61618");
Connection conn = cf.createConnection();
conn.start();
4.3 创建会话:Session,独立的消息队列。支持回滚。
4.3.1创建会话:使用连接创建一个独立的会话。createSession(transacted,acknowledgeMode)。
会话将指定是否支持事务,如果支持(true)则忽略acknowledgeMode。如果为不支持事务(false),则指定处理消息(如何确认接收)的方式。
处理方式:Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,Session.DUPS_OK_ACKNOWLEDGE。
参考:https://docs.oracle.com/javaee/7/api/javax/jms/Session.html#AUTO_ACKNOWLEDGE
示例: Sessionsession=conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
4.3.2创建点对点消息队列:createQueue()。
Queue为点对点消息队列,一条消息只能被一个接收者使用。一个消息队列可以被多个接收方接收,mq自动进行负载平衡。
需要指定消息队列的名称,作为收发双方连接ID。
示例:Destination dest= session.createQueue("TEST.FOO");
4.3.3创建订阅主题:createTopic()。
Topic为点对多消息,一条消息可以被多个接收者使用。默认使用持久化存储。
需要指定主题的名称,作为收发双方连接ID。
参考:http://coderbase64.iteye.com/blog/2081937
示例:Destination dest = session.createTopic("TEST.FOO");
4.4 操作消息:消息的控制对象和内容
4.4.1消息控制对象:生产者MessageProducer,消费者MessageConsumer。
MessageProducer sender =session.createProducer(dest);
MessageConsumer receiver =session.createConsumer(dest);
4.4.2消息内容:createTextMessage()。
可以使用5种消息:
StreamMessage
Java基元值流的消息。其填充和读取均按顺序进行。
MapMessage
一组键--值对的消息。没有定义条目顺序。
TextMessage
Java字符串的消息(例如,XML消息)。
ObjectMessage
序列化Java对象的消息。
BytesMessage
连续字节流的消息。
示例:
Message msg = session.createTextMessage("thisis a msg from sender="+i+","
+ new Date().toString());
4.4.3发送消息:sender.sende(Msg)。
sender.send(msg);
4.4.4接收消息:receiver.receive()。
将阻塞,直至消息到来。
Message msg = receiver.receive();
4.5 关闭消息对象、会话、连接:
// close
receiver.close();
session.close();
conn.close();
5 示例
5.1 示例:点对点收发消息
Sender发送消息后,多个Receiver都能收到消息,但mq服务自动平衡负载,每个消息只能被处理一次。
//activemq.xml
<!--
Licensed to the Apache Software Foundation(ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional informationregarding copyright ownership.
The ASF licenses this file to You under theApache License, Version 2.0
(the "License"); you may not usethis file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreedto in writing, software
distributed under the License isdistributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied.
See the License for the specific languagegoverning permissions and
limitations under the License.
-->
<!-- START SNIPPET:example -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/corehttp://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- Allows us to use system propertiesas variables in this configuration file -->
<beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<propertyname="locations">
<value>file:${activemq.conf}/credentials.properties</value>
</property>
</bean>
<!-- Allows accessing the server log-->
<bean id="logQuery"class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false"scope="singleton"
init-method="start"destroy-method="stop">
</bean>
<!--
The <broker> element is used toconfigure the ActiveMQ broker.
-->
<broker xmlns="http://activemq.apache.org/schema/core"brokerName="localhost" dataDirectory="${activemq.data}">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntrytopic=">" >
<!-- TheconstantPendingMessageLimitStrategy is used to prevent
slow topic consumersto block producers and affect other consumers
by limiting the numberof messages that are retained
For more information, see:
http://activemq.apache.org/slow-consumer-handling.html
-->
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<!--
The managementContext is used toconfigure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses theMBean server that is started by
the JVM. For more information, see:
http://activemq.apache.org/jmx.html
-->
<managementContext>
<managementContextcreateConnector="false"/>
</managementContext>
<!--
Configure message persistence forthe broker. The default persistence
mechanism is the KahaDB store(identified by the kahaDB tag).
For more information, see:
http://activemq.apache.org/persistence.html
-->
<persistenceAdapter>
<kahaDBdirectory="${activemq.data}/kahadb"/>
</persistenceAdapter>
<!--
The systemUsage controls themaximum amount of space the broker will
use before disabling caching and/orslowing down producers. For more information, see:
http://activemq.apache.org/producer-flow-control.html
-->
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsagepercentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsagelimit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsagelimit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
<!--
The transport connectors exposeActiveMQ over a given protocol to
clients and other brokers. For moreinformation, see:
http://activemq.apache.org/configuring-transports.html
-->
<transportConnectors>
<!-- DOS protection, limitconcurrent connections to 1000 and frame size to 100MB -->
<transportConnectorname="openwire"uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="tcp"uri="tcp://0.0.0.0:61618?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="amqp"uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="mqtt"uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnectorname="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
<!-- destroy the spring context onshutdown to stop jetty -->
<shutdownHooks>
<beanxmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook"/>
</shutdownHooks>
</broker>
<!--
Enable web consoles, REST and Ajax APIsand demos
The web consoles requires by defaultlogin, you can disable this in the jetty.xml file
Take a look at${ACTIVEMQ_HOME}/conf/jetty.xml for more details
-->
<importresource="jetty.xml"/>
</beans>
<!-- END SNIPPET: example-->
//Sender.java
import java.util.Date;
import javax.jms.Connection;
import javax.jms.Destination;
importjavax.jms.JMSException;
import javax.jms.Message;
importjavax.jms.MessageProducer;
import javax.jms.Session;
importorg.apache.activemq.ActiveMQConnectionFactory;
/**
* @author sf2gis@163.com
* @date 2015年7月28日上午11:10:51
*
*/
public class Sender {
public static void main(String[] args) throws JMSException,InterruptedException {
// TODO Auto-generated method stub
sendMsg();
}
/**
* send messages to mqserver.
*
* @throws JMSException
* @throwsInterruptedException
*/
public static void sendMsg() throws JMSException,InterruptedException {
// create connection
ActiveMQConnectionFactory cf = newActiveMQConnectionFactory(
"tcp://localhost:61616");
Connection conn = cf.createConnection("admin","admin");
conn.start();
System.out.println("create connection");
// create session
Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
System.out.println("create session");
// create message
Destination dest =session.createQueue("TEST.FOO");
MessageProducer sender = session.createProducer(dest);
for (int i = 0; i < 3; ++i) {
Message msg = session
.createTextMessage("this is a msgfrom sender="+i+","
+ new Date().toString());
sender.send(msg);
Thread.sleep(1000);
}
System.out.println("send a msg");
// close
sender.close();
session.close();
conn.close();
}
}
//Receiver.java
import java.util.Date;
import javax.jms.Connection;
importjavax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
importjavax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
/**
* @author sf2gis@163.com
* @date 2015年7月28日下午3:56:20
*
*/
public class Receiver {
public static void main(String[] args) throws JMSException {
// TODO Auto-generated method stub
receiveMsg();
}
/**
* receive messages frommq server.
*
* @throws JMSException
*/
public static void receiveMsg() throws JMSException {
// create connection
ConnectionFactory cf = new ActiveMQConnectionFactory(
"tcp://localhost:61618");
Connection conn = cf.createConnection();
conn.start();
// create session
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest =session.createQueue("TEST.FOO");
MessageConsumer receiver = session.createConsumer(dest);
System.out.println("waiting msg...");
int i = 0;
while (i != 100) {
Message msg = receiver.receive();
// get msg
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
System.out.println("ReceiveMsg " + i+ "=" + txt.getText()
+ ",now=" + newDate().toString());
} else {
System.out.println(msg);
}
++i;
}
// close
receiver.close();
session.close();
conn.close();
}
}
5.2 示例:订阅收发消息
Sender发送消息后,多个Receiver能同时收到消息。
//activemq.xml
同上。
//Sender.java
import java.util.Date;
import javax.jms.Connection;
import javax.jms.Destination;
importjavax.jms.JMSException;
import javax.jms.Message;
importjavax.jms.MessageProducer;
import javax.jms.Session;
importorg.apache.activemq.ActiveMQConnectionFactory;
/**
* @author sf2gis@163.com
* @date 2015年7月28日上午11:10:51
*
*/
public class Sender {
public static void main(String[] args) throws JMSException,InterruptedException {
// TODO Auto-generated method stub
sendMsg();
}
/**
* send messages to mqserver.
*
* @throws JMSException
* @throwsInterruptedException
*/
public static void sendMsg() throws JMSException,InterruptedException {
// create connection
ActiveMQConnectionFactory cf = newActiveMQConnectionFactory(
"tcp://localhost:61616");
Connection conn = cf.createConnection("admin","admin");
conn.start();
System.out.println("create connection");
// create session
Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
System.out.println("create session");
// create message
Destinationdest = session.createTopic("TEST.FOO");
MessageProducer sender = session.createProducer(dest);
for (int i = 0; i < 3; ++i) {
Message msg = session
.createTextMessage("this is a msgfrom sender="+i+","
+ new Date().toString());
sender.send(msg);
Thread.sleep(1000);
}
System.out.println("send a msg");
// close
sender.close();
session.close();
conn.close();
}
}
//Receiver.java
import java.util.Date;
import javax.jms.Connection;
importjavax.jms.ConnectionFactory;
import javax.jms.Destination;
importjavax.jms.JMSException;
import javax.jms.Message;
importjavax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnectionFactory;
/**
* @author sf2gis@163.com
* @date 2015年7月28日下午3:56:20
*
*/
public class Receiver {
public static void main(String[] args) throws JMSException {
// TODO Auto-generated method stub
receiveMsg();
}
/**
* receive messages frommq server.
*
* @throws JMSException
*/
public static void receiveMsg() throws JMSException {
// create connection
ConnectionFactory cf = new ActiveMQConnectionFactory(
"tcp://localhost:61618");
Connection conn = cf.createConnection();
conn.start();
// create session
Session session = conn.createSession(false,Session.AUTO_ACKNOWLEDGE);
Destinationdest = session.createTopic("TEST.FOO");
MessageConsumer receiver = session.createConsumer(dest);
System.out.println("waiting msg...");
int i = 0;
while (i != 100) {
Message msg = receiver.receive();
// get msg
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
System.out.println("ReceiveMsg " + i+ "=" + txt.getText()
+ ",now=" + newDate().toString());
} else {
System.out.println(msg);
}
++i;
}
// close
receiver.close();
session.close();
conn.close();
}
}
- JMS消息服务-ActiveMQ
- JMS-ActiveMQ:Java消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- Spring jms 和 ActiveMQ 开发消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- Spring+JMS+ActiveMQ+Tomcat实现消息服务
- JMS(Java消息服务)(Activemq简单介绍)
- JMS消息服务器 ActiveMQ
- JMS消息服务器 ActiveMQ
- jms-activemq消息队列
- Spring+JMS+ActiveMQ+Tomcat6.0 实现消息服务
- (六)Spring+JMS+ActiveMQ+Tomcat实现消息服务
- java消息服务使用总结(JMS:通过ActiveMQ实现)
- ActiveMQ - 启动JMS服务
- mvc
- java基础编程中常见的错误(基本类型)
- 为什么我没有收到 “获取Windows 10” 的通知 - Windows 8.1
- 日记(1)
- pandas working with missing data
- JMS消息服务-ActiveMQ
- HDU 1231 最大连续子序列
- 可曾醉過煙雨江南
- Spring MVC详解(六)注解式控制器详解(1)
- cocos2d-x自定义按钮类
- MFC之修改窗口外观
- 冒泡排序 选择排序 快速排序
- hdu 1028 母函数
- hdu 1325 Is It A Tree?