浏览 3461 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-11-11
关于利用oracle侦听线程连发送消息
作为一个非科班出身的程序员,一直不大敢写技术类东西,怕没有深度贻笑大方。最近在坛子里面看到一篇
通知处理来实现松耦合的文章,觉得将自己用的产品心得写出来也还不错,可以练练手,同时也让自己受益,毕竟不能让自己太闲了。 其实上面那篇文章是一个典型的触发器的应用,触发器用处非常广,不管是所谓的基于事件的JSF,或者是Swing的listener,都处都是它的影子,基本所有成熟的商业产品都会加入这么一个特性,对于开发中的作用也是挺大的,我下面谈下我开发中用到的MQ简单侦听器应用。 前年开发的一个银行系统,某银行和人行之间的通信是通过MQ报文进行交互的,而应用服务器的选型是weblogic8.1(太古老了),当时的MQ版本是MQ6.0。这是一个典型的基于消息的应该,就是要求消息一来就要进行相应的处理,当然如果是JMS队列的话,基本上就很简单了,毕竟MDB能够监听它,但是这里是MQ,MQ和WebSphere结合的很好,他可以让MDB监听MQ队列和监听JMS队列一样简单,可以直接配置JMS队列对应MQ队列,但是到了weblogic就不行了,weblogic的JMS队列和MQ是完全没有关系的,也就是说weblogic根本不知道MQ什么时候得到消息,服务器就不能实时的处理业务(该死的厂商不兼容…)。 (基于这个情况我后来查了一些资料,发现BEA和IBM也给出过解决方案,比较复杂,要配置一堆东西。而且和厂商绑定也是很紧,出错了也不知道找谁,我还是倾向我自己的这个方案,这是后话)。 当时有两个选择: 1.轮询MQ对列,有消息就取出来(听着就不大好) 2.“想办法让weblogic服务器知道MQ收到消息” 我们倾向第二种,毕竟由消息来通知比较靠谱,而且轮询比较浪费浪费资源,而且能够实时的得到消息,这时我们就注意到MQ的触发器了: 如图: ![]() 这是一个本地队列的属性选项,它有一个触发器选型,我们可以将它打开,我们可以看到它的触发器类型,具体表示: 第一个(FIRST):当收到第一个消息的时候触发该触发器 每个(EVERY):每收到一个消息都触发 深度(DEPTH):可以配置指定深度的消息时候触发该触发器 触发器被触发的时候会做些什么呢?我们看看还有一个进程名称的输入框(记住我们这里配置为Trigger),也就是说触发器被触发时候会执行该名称的进程 (关于该进程我们在后面会说到)。 脚本如下: define QLOCAL(QUEUE1) put(enable) get(enable) Trigger //表示开通触发器 PROCESS(Trigger) //触发进程 TRIGTYPE(FIRST) //触发器类型为first USAGE(NORMAL) INITQ('SYSTEM.DEFAULT.INITIATION.QUEUE') //初始化队列 REPLACE[/size] 上面我们提到,我们要想办法让服务器知道MQ收到消息了,利用触发器,我们可以很好的做到这点(当然没有直接配置为JMS队列方便了),方案如下: 首先我们在weblogic配置了一个MDB,让他来监听并且处理MQ队列的消息,这是我们的初衷,前面我们说过weblogic的MDB不能监听MQ,所以利用触发来达到这一点,我们假定监听的连接工厂JNDI为jms/connection,JMS队列为queue,首先我们写一个往MDB侦听的JMS队列发送消息的简单程序: import java.util.Hashtable; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; public class Trigger { public static void main(String[] args) { QueueConnection conn = null; try { Hashtable hash = new Hashtable(); hash.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); hash.put(Context.PROVIDER_URL,"t3://localhost:7001"); InitialContext ic = new InitialContext(hash); QueueConnectionFactory factory = (QueueConnectionFactory) ic.lookup("jms/connection"); conn = factory.createQueueConnection(); QueueSession session = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = (Queue) ic.lookup("queue"); QueueSender sender = session.createSender(queue); TextMessage message = session.createTextMessage("Trigger"); sender.send(message); } catch (Exception e) { System.out.println(e.getStackTrace()); } finally { if (conn != null) { try { conn.close(); } catch (Exception e) { System.out.println(e.getStackTrace()); } } } } } 然后我们在服务器上上面编译该java文件 javac Trigger.java,生成 .class文件,然后将该类的路径配置进环境变量。这样我们得到一个发生JMS消息的程序。 记得我们前面提到过进程定义,这也是MQ的一个特征,如图: ![]() 我们可以在队列管理器的高级-----进程定义------------新建进程定义Trigger,我们可以看到一个应用程序标识框,可以输入命令,即标识该经常定义所做的事情,这里我们定义为java Trigger,即给weblogic的MDB监听的JMS队列发送消息,即该进程定义为支持java Trigger命令。 脚本: define process(Trigger) appltype(unix) applicid(java Trigger) 这样,我们的配置就结束了,具体的处理流程是这样的: MQ本地队列收到消息-------》触发触发器----------》执行进程定义--------》java Trigger给MDB的JMS对列发送消息-------》weblogic的MDB收到消息,然后去MQ读取报文,这样就实现了MDB能够知道MQ什么时候收到消息,然后针对进行业务处理了。 这样就实现了weblogic8.1的MDB可以监听MQ队列了,当然了,针对触发器大家还可以做出各种应用,就看具体的需求了。 (不知道9或者以后的版本weblogic能不能直接监听MQ队列) 这样也会产生其他的问题,比如MDB的事务就很难保证,还有出了异常的MQ消息的容错处理,毕竟不是JMS对列,J2EE的事务好像加不上去。 对于触发器(又或者叫侦听器,都是侦听事件然后做出相应的处理),在很多产品都应用,比如DB2的触发器,又或者是WPS流程人工任务的事件处理(这里就不详谈),这也很像我们平时所谈到的pull和push得选择一样,既然很多成熟的产品都选择了这样特性,也说明了它的可取之处,也是push用的比pull多的原因,也许我们在平时开发的过程中加上一点触发器的思想,可能会收到不错的效果。 写的比较乱,如果有错误欢迎大家指出。希望对需要的人有所帮助。 PS:写完不知道往哪里发,以前的厂商分坛找不到了,只能放这里了。。。。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-11-12
《Java实时获取oracle变更》这篇文章描述的其实是streams的内容,和触发器还是有一定区别。
至于楼主谈到的MQ与WEBLOGIC集成,不妨试试外部服务器(foreign server)? |
|
返回顶楼 | |
发表时间:2009-11-12
shevliu 写道 《Java实时获取oracle变更》这篇文章描述的其实是streams的内容,和触发器还是有一定区别。
至于楼主谈到的MQ与WEBLOGIC集成,不妨试试外部服务器(foreign server)? 外部服务器的这种方式我在后面的项目中也试验过,应该是通过本地JNDI来映射到MQ队列,也还不错。我是通过配置本地JNDI来用axis2的webservice来监听报文请求,MQ的报文也会自动被AXIS2监听到,好像外部服务器的方式更加正规一点,呵呵,我这个只是把触发器和发送报文结合了下,算是歪门邪道了~ |
|
返回顶楼 | |