JSR-343学习笔记(JMS)
来源:互联网 发布:淘宝店铺首页大图 编辑:程序博客网 时间:2024/06/05 16:52
JMS两种模式, p2p, pub/sub
Cosuming message from Topic
Nondurable, unshared Subscription[JMSContext.createConsumer()]
Durable Subscriptions
Shared Subscriptions,可以实现负载均衡的目的
Controlling Message Acknowledgment
成功消费了一条message体现在3点<1>client接收到消息<2>client处理了消息<3>消息被acknowledged
对于locally transacted session,当session提交时消息会被acknowledged,如果调用context.rollback(),消息会被重发(redeliver)
对于JTA transaction(JaveEE web 或者EJB),当事务提交时,消息会被acknowledged
对于 non-transacted session, 消息如何被acknowledged取决于调用createContext时传入的参数
JMSContext.AUTO_ACKNOWLEDGE,在client调用receive方法返回(对于a中的3点,这个是个例外)或者MessageListener返回成功是,消息会被自动acknowledged
JMSContext.CLIENT_ACKNOWLEDGE,手动调用Message的acknowledge方法,会对所有已消费的messages进行acknowledge,只能用在application client,不能用在web组件和EJB中
JMSContext.DUPS_OK_ACKNOWLEDGE,出否可以接收重复的消息
对于未能及时进行acknowledge的处理情况
如果是从queue读
provider会保留消息,等下次消费者访问queue会重发(redeliver)
如果是从topic读
如果是从建立的持续(durable)订阅关掉了JMSContext, Provider会保留消息
如果是从建立的非持续(non-durable)订阅关掉了JMSContext,Provider会丢弃掉这些消息
对于non-transacted session
如果是durable订阅,使用JMSContext.recover会重新接收自上次acknowledge之后的消息,但是顺序有可能不同
如果是non-durable订阅,调用recover()方法会丢弃所有unacknowledge的消息
发送消息时的一些选项
设定消息的持久性(默认是PERSISTENT,也可以是NON_PERSISTENT),non的话对于provider就不进行消息持久化存储了,该特性可以通过Provider的setDeliveryMode方法进行设定
设定消息的优先级,从0(最低级)到9(最高级),默认是4,Provider会尽量有优先发送高优先级的消息,通过setPriority()进行设定
设定消息过期,如股票实时报价,在一定时间后就没有意义了,类似场景可以设定消息有效期间,通过Producer的setTimeToLive方法可以设定,单位毫秒,默认为0(永久有效)
设定延时发送,可以通过Producer的setDeliveryDelay方法进行设定,单位毫秒
临时发送地(Temporary Destinations)【天啊,看英文文档实在是不知道怎么翻译成中文,还是个复数】
可以通过JMSContext创建临时的发送目的地
使用JMS本地事务
在application client 或者 Java SE client,可以在创建上下文的时候以SESSION_TRANSACTED参数创建local transaction(connectionFactory.createContext(JMSContext.SESSION_TRANSACTED)),之后通过context.submit()和context.rollback()进行事务操作
在Java EE和EJB中,不能使用本地事务,需要使用JTA事务
异步发送消息
目前异步发送消息只能用在application client和 J2SE client,通过在Producer上设定异步回调来实现(setAsync)
在JaveEE中使用JMS
JaveEE中,每个connection只能创建1个JMSContext
可以通过annotation和DD(deployment descriptor)的方式创建资源(Destination和ConnectionFactory)
在javaEE web component, session bean, message driven bean中注入connectionFactory和Topic/Queue时,不能声明为static的,注入factory之后要取得jmsContext需要再进行创建
- 1234
@Resource
(lookup =
"java:comp/DefaultJMSConnectionFactory"
)
private
ConnectionFactory connectionFactory;
@Resource
(lookup =
"jms/MyTopic"
)
private
Topic topic;
提供了直接注入JMSContext的方式,可以直接使用@Inject方式,使用默认factory可以用第一种,使用自定义Factory可以使用第二种方式
- 123456
@Inject
private
JMSContext context1;
@Inject
@JMSConnectionFactory
(
"jms/MyConnectionFactory"
)
private
JMSContext context2;
在JaveEE web中和EJB中对JMSContext的管理,及时关掉不用的jmsContext是非常重要的
如果只在某个业务方法里面使用,可以使用JDK的try-with-resources方式去创建JMSContext
如果在事务或者请求中,可以使用直接注入JMSContext 的方式(@Inject JMSContext context;)
EJB中可以在回调函数@PostConstruct 和 @PreDestory维护context但是一般来说没有必要,如果是有状态Bean(Stateful Bean)可以在@PrePassivate和@PostActivate中处理
在JaveEE中,事务的控制
一般使用默认的容器控制的事务(JTA)即可
也可以使用bean管理的事务 java.transaction.UserTransaction进行控制
使用消息驱动Bean进行异步消息接收
必须以@MessageDriven注解,或是使用DD(deployment descriptor)
必须是public类,并且不能是抽象或者final
必须包含无参公有构造函数
可选实现MessageListener接口(否则没有意义啊)
消息驱动Bean和application client的区别如下
后者需要依次创建JMSContext, JMSConsumer, setMessageListener,对于前者是自动的
使用@MessageDriven注解的Bean会包含一个activationConfig注解
前者可以有多个实例,后者对于一个MessageListener只能是一个线程
对于前者,acknowledge过程是自动处理的,除非使用Bean管理的事务(UserTransaction)
如果JMS和应用服务器(jboss, glassfish等)通过resource adapter进行了整合,可以通过它去handle事务的管理 @Resource private MessageDrivenContext mdc;
管理JTA事务,JTA事务可以是分布式的,EJB和web容器中的JTA事务分2种
容器管理的事务(EJB会默认使用Required级别的事务)
Bean管理的事务,使用UserTransaction进行手动提交或回滚
对应专家可以使用手动控制事务的模式,这样可以实现提交一部分事务,然后再开多个事务,还可以让一部分JMS消息在事务外先处理并且acknowledge然后让一部分消息处于事务中处理
在JTA事务中创建的JMSContext任何参数都将被忽略,因为容器会管理所有的属性
在non-JTA事务中创建的JMSContext只能是AUTO_ACKNOWLEDGE或者DUPS_OK_ACKNOWLEDGE
如果是用Bean管理的事务,不能在其中进行acknowledge,只能通过属性设置activation configuration的属性:acknowledgeMode来实现,可以设置成AUTO_ACKNOWLEDGE或者DUPS_OK_ACKNOWLEDGE
如果在onMessage中抛出了RuntimeException,那么容器不会进行acknowledge,会在未来对消息进行重新发送(redeliver)
该JSR的DD(deployment descriptor)为:glassfish-resources.xml
对应DTD: http://glassfish.org/dtds/glassfish-resources_1_5.dtd
END
- JSR-343学习笔记(JMS)
- JSR-338 学习笔记(JPA)
- JMS学习笔记
- Jms---ActiveMQ学习笔记
- JMS学习笔记1
- JMS学习笔记2
- JMS学习笔记3
- JMS学习笔记4
- JMS学习笔记5
- JMS学习笔记6
- JMS学习笔记7
- JMS学习笔记
- JMS学习笔记
- JMS学习笔记
- jms 学习笔记
- jms学习笔记GOOD
- 《JMS学习笔记》
- JMS-ActiveMQ学习笔记
- 自定义ListView侧滑删除 畅所欲滑,删你想删
- 配置apache的vhost出现的问题和解决方法。
- Cocos2d 屏幕适配方案
- 正则 re中要转义的特殊字符
- StringUtils:将一个InputStream流转换成字符串
- JSR-343学习笔记(JMS)
- 堆栈程序内存分配详解
- Android小知识——按钮点击的变化
- JS 获取当前时间
- Android Studio的快捷键
- xutils请求shh框架发布的json数据(类似from表单)
- 使用Enumeration和Iterator遍历集合类
- android小知识——时间与时间戳之间的转化
- POJ3469