#关于事务:

activemq 遇到的不能消息确认的问题。

Session session = connection.createSession(Boolean.FALSE,   Session.AUTO_ACKNOWLEDGE);

有两种情况:

1 开启事务
当createSession第一个参数为true时,表示创建的session被标记为transactional的,确认消息就通过确认和校正来自动地处理,第二个参数应该是没用的。   此时需要我们手动 session.commit(); , 否则此session发送的消息是不会发送到activemq 中去,而只是存在于当前jvm 内存..

2 不开启事务
当createSession的第一个参数为false时,表示创建的session没有标记为transactional, 此时不能执行session.commit(), 否则报错的, 因为:

    public void commit() throws JMSException {
this.checkClosed();
if (!this.getTransacted()) {
throw new IllegalStateException("Not a transacted session");
} else {
if (LOG.isDebugEnabled()) {
LOG.debug(this.getSessionId() + " Transaction Commit :" + this.transactionContext.getTransactionId());
} this.transactionContext.commit();
}
}

此时有三种用于消息确认的选项: 
**AUTO_ACKNOWLEDGE session将自动地确认收到的一则消息; 
**CLIENT_ACKNOWLEDGE 客户端程序将确认收到的一则消息,调用这则消息的确认方法; 
**DUPS_OK_ACKNOWLEDGE 这个选项命令session“懒散的”确认消息传递,可以想到,这将导致消息提供者传递的一些复制消息可能出错。

#关于消息持久化:

有两种方式NON_PERSISTENT、PERSISTENT

MS有两种消息传递方式。标记为NON_PERSISTENT的消息最多传递一次,而标记为PERSISTENT的消息将使用暂存后再转发的机理投递。如果一个JMS服务离线,那么持久性消息不会丢失,但是得等到这个服务恢复联机的时候才会被传递。所以默认的消息传递方式是非持久性的,虽然使用非持久性消息可能降低内存和需要的存储器,但这种传递方式只有当你不需要接收所有消息时才使用。

我自己的理解:  持久化的消息呢, activemq 服务器重启后, 消息还在,  非持久化的消息activemq 服务器重启后, 消息就不在了..

#关于消息无法消费:

消息无法消费通常有各种各样的原因,  这里说的是connection 关闭过早的问题:

下面的代码, 如果  consume();后面直接,      close(); 的话, MessageListener 是消费不到的, 因为 还没来得及消费, connection 就已经关闭了啊..

有一种情况例外,:  consumer.receive(TIME_IN_MILLISECONDS); 方法,    我测试的时候, 如果把 setMessageListener 改成receive, 那么,  我们是可以消费到一条消息的( 只要queue 存在未消费消息 )...

public class TestActiveMq{
private static final int SEND_NUMBER = 5;
static ConnectionFactory connectionFactory;
// Connection :JMS 客户端到JMS Provider 的连接
static Connection connection = null;
static String admin = "admin";
static String pass = "admin";
static String brokerUrl = "tcp://10.10.10.123:61616"; public static void main(String[] args) throws Exception {
init();
consume();
Thread.sleep(2000);
close();
} public static void init() {
// ConnectionFactory :连接工厂,JMS 用它创建连接
// Session: 一个发送或接收消息的线程
// TextMessage message;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(
admin,
pass,
// ActiveMQConnection.DEFAULT_PASSWORD,
brokerUrl);
((ActiveMQConnectionFactory) connectionFactory).setTrustAllPackages(true);
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
// 获取操作连接
} catch (Exception e) {
e.printStackTrace();
} finally {
}
} public static void close() {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
} /**
*
* 队列操作
*/
public static void consume() throws JMSException {
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
String qu = null;
qu = "test-persistence";
Queue queue = session.createQueue(qu);
MessageConsumer consumer = session.createConsumer(queue); System.out.println("consumer = " + consumer);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
System.out.println("message00 ============ " + message);
try {
message.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
} public static void sendMessage()
throws Exception {
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// MessageProducer:消息发送者
MessageProducer producer; session = connection.createSession(Boolean.FALSE,
Session.AUTO_ACKNOWLEDGE);
// 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
destination = session.createQueue("test-persistence");
// 得到消息生成者【发送者】
producer = session.createProducer(destination);
// 设置不持久化,可以更改
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); for (int i = 1; i <= SEND_NUMBER; i++) {
TextMessage message = session
.createTextMessage("ActiveMq 发送的消息" + i);
// 发送消息到目的地方
System.out.println("发送消息:" + i); long delay = 5 * 1000;
long period = 10 * 1000;
int repeat = 5;
// message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
// message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
// message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
// message.setJMSExpiration(2);
// message.setJMSTimestamp(period); // producer.setTimeToLive(0);
producer.send(message);
} // session.commit();
} /**
*
* 队列操作
*/
public static Object browser() throws JMSException {
Session session = connection.createSession(false, 2);
String qu = null;
qu = "test-persistence";
Queue queue = session.createQueue(qu);
QueueBrowser browser = session.createBrowser(queue);
List<String> msgList = new ArrayList<>();
Enumeration enumeration = browser.getEnumeration();
while (enumeration.hasMoreElements()) {
// ObjectMessage o = (ObjectMessage) enumeration.nextElement();
Object o = enumeration.nextElement();
System.out.println("o = " + o);
// MessageDto object = (MessageDto) o.getObject();
// System.out.println("object = " + object);
// msgList.add(object.toString());
}
return enumeration;
} }

参考

http://riddickbryant.iteye.com/blog/441890

http://blog.sina.com.cn/s/blog_4d22b9720102uxyr.html

https://blog.csdn.net/zishan007/article/details/45037731

https://blog.csdn.net/wsyyyyy/article/details/79888793

https://blog.csdn.net/seven__________7/article/details/69317106

activemq 的那些事1的更多相关文章

  1. (jms)ActiveMQ 安装配置.

    前言 ActiveMQ他是Apache出品的一个JMS提供者,管理会话和队列,运行在JVM下,支持多种语言,如JAVA,C++,C#,应用协议: OpenWire,Stomp REST,WS Noti ...

  2. Spring下ActiveMQ实战

    MessageQueue是分布式的系统里经常要用到的组件,一般来说,当需要把消息跨网段.跨集群的分发出去,就可以用这个.一些典型的示例就是: 1.集群A中的消息需要发送给多个机器共享: 2.集群A中消 ...

  3. 工业物联网或系统集成中应用消息队列(ActiveMQ,C#的demo)的场景全面分析

    1.[连载]<C#通讯(串口和网络)框架的设计与实现> 2.[开源]C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 2.应用SuperIO(SIO)和开源跨平台物联网框 ...

  4. ActiveMQ的初夜

    Producer Flow Control mq自己实现了Flow Control(流量控制,默认开启),在mq的版本中,4.x和5.x流量控制实现原理并不相同,前者通过 TCP Flow Contr ...

  5. 开源 VS 商业,消息中间件你不知道的那些事

    11月23日,新炬网络中间件技术专家刘拓老师在DBA+社群中间件用户组进行了一次主题为“开源 VS 商业,消息中间件你不知道的那些事”的线上分享.小编特别整理出其中精华内容,供大家学习交流. 嘉宾简介 ...

  6. ActiveMQ相关背景(转)

    概述 介绍中间件.MOM.JMS.ActiveMQ,及相互的关系. 中间件 由于业务的不同.技术的发展.硬件和软件的选择有所差别,导致了异构组件或应用并存的局面.要使这些异构的组件协同工作,一个有效的 ...

  7. JMS and ActiveMQ first lesson(转)

    JMS and ActiveMQ first lesson -- jms基础概念和应用场景 2011-6-18 PM 9:30 主讲:kimmking <kimmking@163.com> ...

  8. 关于ActiveMQ的一点总结

    ActiveMQ入门 作者:一路向北 摘要:本文主要讲述ActiveMQ的基本知识和使用方法,并简单结合spring使用ActiveMQ. 一.ActiveMQ特性和使用总览 企业消息软件从80年代起 ...

  9. 消息队列-ActiveMQ

    1 业务需求描述 举例描述: 再警情通报的业务时通过发送消息界面可以选择 警情联络,和船情通报两种消息 发送方式可分为 一对一发送:部门对部门.个人对个人 一对多发送:部门对多部门.个人对多人 2 功 ...

随机推荐

  1. 移动端H5拍照代码实现及外网部署

    最近的工作中,遇到了一个需求:对于无APP登陆权限的人员,提供拍照上传功能,以便生成更完善的出工记录.经研究讨论,决定实现的机制为:由合法的人员登陆APP认领相关工作任务,并生成当天当工作的唯一二维码 ...

  2. vue导出excel

    1.按装依赖 cnpm install -S file-saver xlsx cnpm install -D script-loader 2.引入Blob.js和expor2Excal.js 3.在m ...

  3. flex 1与flex auto

    flex意为"弹性布局" 这次主要探究的是flex:1与flex:auto的区别,flex是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 ...

  4. Locust 集合点

    直接编写接口事务脚本对后台接口进行测试:有时测试需要让所有并发用户完成初始化后再进行压力测试,这就需要类似于LoadRunner中的集合点的概念,由于框架本身没有直接封装,有如下办法实现: from ...

  5. Spring3(一) 控制反转(IoC)和依赖注入(DI)

    几个常用框架之间的关系 1       spring框架概述 1.1   什么是spring Spring是一个开源.轻量级的Java 开发框架.框架的主要优势之一就是其分层架构,分层架构允许使用者选 ...

  6. Python全栈之路----流程控制+循环

    (一)流程控制 1.单分支结构    if  条件: 满足条件后要执行的代码 2.双分支结构: if  条件: 满足条件后要执行的代码 else : if 不满足就执行这个代码 3.多分支结构:if ...

  7. 2018.4.27 java容器

    一.容器的概念 在Java当中,如果有一个类专门用来存放其它类的对象,这个类就叫做容器,或者就叫做集合,集合就是将若干性质相同或相近的类对象组合在一起而形成的一个整体 二.容器与数组的关系 之所以需要 ...

  8. hibernate多对多关系

    package com.manytomany; import java.util.HashSet; import java.util.Set; public class Student { priva ...

  9. 使用 jest 测试 react component 的配置,踩坑。

    首先安装依赖 npm i jest -g npm i jest babel-jest identity-obj-proxy enzyme enzyme-adapter-react-15.4 react ...

  10. C# 线程安全集合

    转载 对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行访问.经常要做的就是对一些队列进行加锁-解锁,然后执行类似插入,删除等等互斥操作. .NetFramework 4.0 中提供了一些 ...