使用Hibernate和JMS开发异步日志服务

获益于异步日志服务

使用HibernateJMS开发异步日志服务

摘要

在软件开发中,日志是一个相当重要的组件,特别是对于软件的健壮性而言。通常,日志服务是同步的,会带来额外的性能开销(特别是在紧急的情况下)。这样的日志服务不能有效地作为分布式日志服务。在一个分布的计算环境中,比如J2EE,客户端期望日志能够被并发的记录到中央数据库,J2EE架构不提倡将日志记录到文件或者打印到控制台。做为JMS的一个应用,你可以使用异步的日志服务来代替通常的同步日志服务. 这样客户端便能在不阻塞的情况下继续执行. 在可靠模式(guaranteed mode)下,日志数据被提交(且仅仅被提交一次)到目的地(destination),接下来,日志信息将被Hibernate轻松的持久。这篇文章就是介绍如何使用HibernateJMS来开发一个异步的日志服务。

正文

开发一个通用的日志服务通常会引发争论。现在,已经有相当多的日志框架可用,这些日志服务是由专职人员或者开源社区开发的,特别应该提到Log4jJ2SE1.4的日志。由于许多日志框架都是在JMSJava消息服务-Java Message Service)还没有问世前开发的,并没有使用异步日志。在JMS问世后,框架被设计,以便能使用异步日志。

在传统的同步日志模型里,在日志服务调用没有成功返回前,调用者是不能往下执行的,所有的调用者都被阻塞,直到记录被持久或被日志服务所接收。显然,那样会导致额外的开销,特别是当一个应用被设计来记录大量的日志信息。想像一个日志文件有大量的(通常是数百)日志语句组成,每一条日志信息都应该在下一个日志被处理前记录完成,这是一个相当耗时处理过程。在分布计算环境中,客户端是并发运行的,可选择的方法是使用传统的日志服务创建并发的客户端,虽然性能是个问题。分布式计算框架会部署到很多服务器上(物理上相似的或者不相似的许多地方),在这种情况下,记录日志到中心数据库是相当烦琐的,而且也几乎不可能

本文将引导你开发一个简单的日志服务。创建一些日志信息,通过网络发送到JMS提供者,并且持久到数据库。为这个目的,我们使用JMS来实现异步、使用Hibernate来持久数据。你可以以多种方式持久数据,比如标准的JDBCJava Database Connectivity)连接、EJBEnterprise JavaBean),或者存储过程。我推荐使用工具从传统的POJOplain-old Java objects)创建实体域。在这篇文章里,我使用Hibernate,来替代原先使用EJB构建的实体模型

在开发日志服务前,让我们来了解下一些重要概念,这些概念关系到这次的应用开发。

企业级消息(Enterprise JavaBean

J2EE关于分布计算环境还在继续完善,我们能够补充它的许多特性,比如JMS,以开发异步服务。JMSSUN微系统的一个规范,并且适用于在标准的应用程序间通讯。参考资源部分,下载这个规范,Third-party vendors 实现了Sun定义的这个规范。JMS被设计用来处理不同的消息类型(消息无需知道自己持有的信息)

远程过程调用(RPC)模型,比如RMI(远程方法调用-remote method invocation)、SOAP(简单对象访问协议-Simple Object Access Protocol)、ORB(对象请求代理-object request broker)等是中央接口的,意味着发布者期望一个返回值。在使用JMS环境中,发送者并不了解接收者。接收和发送消息的应用依赖于特定的通道,但是他们并不通讯,实际上,他们只是被委托去传输消息给JMS提供者,应用程序发送消息到目的地后,他们的工作也就完成了。

消息类别

JMS 提供两种消模型,点对点(porint-to-porint)和发布/订阅(publish/subscribe)。点对点是基于队列的消息模型,每一个客户端都发送消息到一个目的队列,这些消息存在一个栈里。消息也可以被持久化,以保证服务器当机时,数据仍然可用。JMS提供者投递到达堆栈的消息,以供给消费者。在点对点模型里,一个消息只能被投递给一个消费者。
在发布/订阅是广播模型,在该模型中,所有对某一特定主题感兴趣的客户端,把自己注册为一个监听。发布者发布它的消息到目的地(主题),JMS提供者负责分发消息给这些监听。在这个模式中,所有的监听都会消费每一个消息

消息驱动Bean

EJB2.0介绍了一种新的Bean组件类型:消息驱动BeanMDB)。该Bean不响应客户端的调用。事实上,没有提供任何接口使得客户端可以调用MDB。当收到特定的JMS消息时,只有容器才激活MDBMDB仅仅是消息消费者,MDB的执行是简洁的,所有的JMS管理信息都在部署中被描述,在onMessage函数里,接收和处理消息的行为按照部署执行。查看资源部分,获取更多MDBs信息

Hibernate

Hibernate是用于免除JDBC编码的开源产品。这是一个在java环境实现OR映射的工具,它在Java 对象和数据库实体间建立映射。在企业开发中,对象关系映射是一个关键需求,产生的或者修改的数据必须被持久。数据持久是开发人员的一个恶梦,尤其是需求的多边,而导致数据模型的修改。Hiberante可以减轻数据持久的复杂化。查看资源部分以了解Hibernate的更多信息,本文介绍开发的日志服务,将使用Hibernate作为OR持久的媒介。

异步日志服务

在上面的几节,我简单的介绍了开发这个日志服务所需的主要技术。现在让我们使用JMSHibernate来开发一个简单的框架。

概要的讲一下,异步日志服务是如下工作:客户端创建一个日志消息LogMessageValue Object),要求辅助类(JMSLogger)发布这个消息到队列。辅助类(JMSLoger)使用日志消息来创建一个JMSObject Message,然后提交到队列。一旦消息到达,容器就调用监听这个队列的MDB,访问它的onMessage回调方法。MDB读取消息(LogMessage),然后使用Hibernate持久消息到数据库

日志服务使用JMS的点对点消息方式。一旦一个日志消息被送出,客户端不需要担心日志消息被送到了哪里,或者它是否被发送。客户端信任JMS的消息机制,保证消息被投递。

下面的图例说明了日志服务的主要组成

功能框架:日志服务的主要组件

框架组件

在分析实现细节前,让我们来仔细看一下这些组件,日志程序是这个应用的入口点,作为非J2EE的客户端使用,这与J2EE客户端只有较小的差异。日志程序使用JMSLogger发送消息到队列,它创建一个日志消息(LogMessage),然后由JMSLogger发送到LogMessageQueue目的地

JMSLogger是一个JMS类,一旦被实例化,它就关联自己到消息目的地。因此,当JMSLogger被日志程序创建,它就通过JNIDIJava命名目录访问接口-Java Naming and Directory Interface)命名空间查找连接工厂(Connection Factory)和队列(Queue),然后开启和JMS提供者(JMS Provider)的会话(Session),接下来,JMSLogger就发送消息到目的地。应用客户端通过简单的实例化日志程序和调用它的方法来访问日志服务。在J2EE环境下,日志服务只在应用服务启动的时候被实例化一次,当应用服务启动时,使用Java管理扩展(JMXJava Management Extensions)来管理Beans,这样客户端便能通过JNDI查找到这个服务,然后象往常一样,调用它的方法来持久日志消息

LogMessageQueue是日志消息发送的目的地,一个MDB监听这个队列。一旦消息到达队列,EJB容器就调用MDB,并且委派它作更多的处理。MDB取出日志消息(LogMessage),通过Hiberante的持久机制,持久日志消息到数据库。

LogMessage是一个被持久的含有日志信息的Java对象。它被设计成用来持有日志信息,比如简洁描述、详细描述、日志时间和日志级别。

实现

现在,我将详细描述日志服务的实现,在资源部分,你能下载所有的实现代码,然后解压到本地目录。

创建日志表格</

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值