
基于回调机制异步日志服务开发.doc
8页基于回调机制异步日志服务开发【摘要】日志服务作为软件开发中的一个重要组件,同步 将带来额外的系统开销本文介绍了一种利用回调机制开发 异步日志服务的方法,有效地减少了系统性能的开销,提高 了软件的健壮性关键词】异步日志服务;回调机制;Hibernate1. 引言在分布式计算环境中,通常使用传统的同步日志服务创 建并发的客户端,分布式计算框架会部署到许多物理位置上 完全不同的服务器上,在这种环境下,记录所有日志到中心 数据库就显得相当繁琐一一系统本身的调用阻塞会带来巨 大的系统开销,使得日志服务几乎不可能完成异步日志服 务可有效的解决上述问题,在可靠模式(guaranteed mode) 下,日志数据仅被提交一次到目的地便被Hibernate轻松的 持久,减少了额外的系统开销,使客户端的业务执行更加流 畅,较好地提高了软件的健壮性2. 回调机制概述软件模块之间的接口调用方式一般可分为三类:同步调 用、回调和异步调用同步调用是一种阻塞式调用,调用方 要等待对方执行完毕才返回,它是一种单向调用;异步调用 是一种类似消息或事件的机制,不过它的调用方向刚好相 反,接口的服务在收到某种信息或发生某种事件时,会主动 通知调用客户方的接口;回调是一种双向调用模式,也就是 说,被调用方在接口被调用时也会调用对方的接口。
回调和 异步调用的关系非常紧密,通常我们使用回调来实现异步消 息的注册,通过异步调用来实现消息的通知,回调常常被认 为是异步调用的基础图1接口调用的三种方式对于不同类型的语言、平台(Win32.JDK)或构架(CORBA、DCOM、WebService),客户和服务 的交互除了同步方式以外,都需要具备一定的异步通知机 制,让服务方(或接口提供方)在某些情况下能够主动通知 客户,而回调是实现异步的一个最简捷的途径3•异步日志服务的框架传统的同步日志模型中,日志服务调用没有成功返回 前,调用者是不能往下执行的,所有的调用都被阻塞,直到 记录被持久或被日志服务所接收显然,当一个应用被设计 用来记录大量的日志信息,每一条日志信息都必须在下一个 日志被处理前完成记录,这将会是一个相当耗时处理过程一个通用的异步日志服务包括如下组件:客户端创建一 个日志消息LogMessage(Value Object),要求辅助类(JMSLogger)发布这个 消息到队列;辅助类(JMSLoger)使用日志消息来创建一个 JMS 的 Object Message,然后提交到队列 Message Queue; 一旦消息到达,容器就调用监听这个队列的MDB,访问它的 onMessage回调方法;MDB读取消息(LogMessage),然后使 用Hibernate持久消息到数据库。
因为可以把调用者与被调用者分开,调用者不再关心谁 是被调用者,即客户端信任JMS的消息机制,从而无需考虑 日志消息的传送过程日志服务使用JMS的点对点消息方式, 保证了消息被可靠地投递图2说明了一个通用的异步日志 服务的主要框架组件图2日志服务的功能框架图4.开发实例下面通过一个实例来展示回调机制在开发一个简单的 异步日志服务中的应用本实例的主要流程是:创建一些日 志信息,通过网络发送到JMS提供者,并且持久到数据库 为达到这个目的,本例中使用JMS来实现异步、访问 onMessage实现回调、使用Hibernate来持久数据图3是 JMS API Programming Model 的模型示意图[1]图3. JMS对象模型回调机制的基本思想就是调用者在初始化一个对象时, 将一些参数传递给对象,同时将一个调用者可以访问的函数 地址传递给该对象这个函数就是调用者和被调用者之间的 一种通知约定,当约定的事件发生时,被调用者就会按照回调函数地址调用该函数下面展示开发实例:not—null二"false” />3、回调private void persistMessage(LogMessage message) throwsHibernateException {net・sf. hibernate .Session session 二 null;SessionFactory sessionFactory 二 null;Transaction tx = null;try {// Create a session factory from the configuration(hibernate.properties// File should be present in the class path) sessionFactory 二 new Configuration()・addClass(LogMessage・ class)・buildSessionFactory ();// Create a sessionsession = sessionFactory. openSession();// Begin a transactiontx 二 session. beginTransaction ();} catch (. .) { try {// Assign the message idmessage・ setMessageld (“ “+System. currentTimeMillis ());// Save the object to the dat abase and comm it the transactionsession. save(message);tx. commit ();}catch(Exception ex) {}finally {// Close the sessionsession. close ();}}4、实现日志持久sessionFactory = new Configuration(). addClass(LogMessage・ class)・ buildSessionFactory ();session = sessionFactory. openSession(); tx = session.beginTTansaction ();message・ setMessageld(“ “+System. currentTinieMillis ());// Save the object to the database・session. save(message);tx. commit ();正如我们所看到的,一旦确定对象的关系映射文件,持 久的日志信息将会很容易地进入到数据库中,而hibernate 将在后台处理好一切相关的工作。
本实例的开发包括三个清 晰的开发步骤:第一步:创建应用入口日志程序是这个应用的入口点,日志程序使用 JMSLogger发送消息到队列,它创建一个日志消息 (LogMessage),然后由 JMSLogger 发送到 LogMessageQueue 目的地JMSLogger是一个JMS类,一旦被实例化,它就关联 自己到消息目的地因此,当JMSLogger被日志程序创建, 它就通过JNIDI命名空间查找连接工厂(Connection Factory)和队列(Queue),然后开启和JMS提供者(JMS Provider)的会话(Session),第二步:实现回调接下来,JMSLogger发送消息到目的地应用客户端通 过简单的实例化日志程序和调用它的方法来访问日志服务 在J2EE环境下,日志服务只在应用服务启动的时候被实例 化一次,当应用服务启动时,使用Java管理扩展来管理 Beans,这样客户端便能通过JNDI查找到这个服务,然后像 往常一样,调用它的方法来持久日志消息第三步:实现日志持久LogMessageQueue是日志消息发送的目的地,一个MDB 监听这个队列一旦消息到达队列,EJB容器就调用MDB, 并且委派它作更多的处理。
MDB取出日志消息(LogMessage), 通过Hiberante的持久机制,持久日志消息到数据库5. 结语利用回调机制开发的异步日志服务,提供了许多其他分 布式对象计算模型没有的优点,如:日志产生者和调用者之 间的“松耦合”,系统的高可扩展性,以及高度的可靠性 上述优势的存在,解决了同步日志系统中存在的代码混乱、 紧耦合和执行效率低下等问题,它还有具有一些别的好处: 对于使用者,消息的产生、传递是透明的[2]这就为建立 动态的、可靠的和灵活的应用系统提供了很好的组件比如, 日志服务是许多应用程序的基础,这些应用程序可以是工作 流,网络管理,通信服务或供应链管理程序等参考文献[1] 何文涛,冯勇卫.中间件服务器上MDB持久化消息的 探讨[J] •微电子学与计算机,2008 (04).[2] 曾斌,彭长根,杨辉,等.基于J2EE技术的企业异步通 信解决方案[J] •计算机工程,2006(05).作者简介:叶小莺(1980—),湖南长沙人,助教,主 要从事计算机教学及教学管理工作。
