|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2008-07-15
最近我在负责公司各项目的通用日志组件的设计和开发,而各项目组考虑得最多的一个问题是性能问题。抽象来看,日志处理分为:日志收集、日志保存、日志查询、日志分析几个主要部分。日志收集必须由应用程序完成,这部分工作可以使用AOP来减少对应用逻辑的干扰,但问题是:日志收集和日志保存都需要损耗系统资源,让系统变得更慢,某些情况下,对于一些简单的业务操作,日志处理所占用的时间可能比业务操作占用的时间更长。所以,最大限度的减少日志处理对应用程序的性能损耗是日志组件需要解决的一个重要问题。
我曾经想过利用JMS把日志信息发送到另外一台服务器,由专门的日志服务器来负责日志信息的持久化(注:对比日志信息收集逻辑,日志信息持久化通常占用了更多的系统资源),通过这种分布式运算来减轻应用程序服务器的负担。但这样做始终存在一个问题:如果日志信息要与业务操作保持一致(即只要业务操作被提交,日志信息必须保证被成功记录下来),那么就必须保证日志信息与业务操作的事务一致性,如果选择在等等JMS服务器答复之后才提交业务操作事务,这种方案是不能被接受的,因为无法预知JMS服务器答复的时间,而如果不采用这种方案,则日志信息在发送到JMS服务器到JMS服务器给出答复这段时间,必须在本地进行持久化,直到JMS服务器确认信息已经被成功接收,本地的日志记录才能被移除,而这样一来,实际上日志信息还是必须在本地被持久化一次,而且将来应用程序服务器还必须分心去完成JMS的回复处理和本地日志信息的清理,事实上没有达到分布式运算的目的。 请问大家有没有什么比较好的建议,谢谢! 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2008-07-15
对于磁盘I/O快的牛X机器来说,写日志不算什么,日志并不会导致系统瓶颈。而且通过设定优先级,在系统真正运行的时候输出的日志也仅是少量的INFO级以上信息。另外写日志的时候也可以通过异步来写,不过你说日志作为事务的一部分,就不能这么做了。
|
|
| 返回顶楼 | |
|
时间:2008-07-15
javazhujf 写道 对于磁盘I/O快的牛X机器来说,写日志不算什么,日志并不会导致系统瓶颈。而且通过设定优先级,在系统真正运行的时候输出的日志也仅是少量的INFO级以上信息。另外写日志的时候也可以通过异步来写,不过你说日志作为事务的一部分,就不能这么做了。
我现在要做的日志组件不同于传统的日志(Log4J、JDK Logging等),这些日志信息不是基于代码级的,而是基于业务级的,所以不存在“级别”(INFO之类)的问题,只要应用程序有需求,就要记录日志。现在问题就在于要保持事务一致的情况下如何降低对应用程序的影响,我曾经做过数据移植程序,发现数据持久化的瓶颈在于写入数据库的时刻,用JDBC向数据库写入一条数据是毫秒级的,如果一次写入1000条以上,对应用程序的影响就比较明显了。 |
|
| 返回顶楼 | |
|
时间:2008-07-15
我认为可以采用异步和Buffer的方式,比如有专门负责写日志的线程,这个线程负责从队列中读取到一条条的日志然后进行写操作,而应用只需要把日志放到队列里就可以了。至于如何保证“即只要业务操作被提交,日志信息必须保证被成功记录下来”,因为写日志出错的机会比较小,可以让写日志的线程负责一定要把每一条成功写入,除非发生系统级ERROR。
或者不是用自己服务器的线程,而是用你说的JMS服务器,要求这个服务器写日志一定成功,否则发生系统级异常的时候,中止JMS服务器,而应用监测到JMS服务器停止的时候也会发生系统异常。 |
|
| 返回顶楼 | |
|
时间:2008-07-15
javazhujf 写道 我认为可以采用异步和Buffer的方式,比如有专门负责写日志的线程,这个线程负责从队列中读取到一条条的日志然后进行写操作,而应用只需要把日志放到队列里就可以了。至于如何保证“即只要业务操作被提交,日志信息必须保证被成功记录下来”,因为写日志出错的机会比较小,可以让写日志的线程负责一定要把每一条成功写入,除非发生系统级ERROR。
现在我主要担心的就是系统级的无法预知的ERROR,比如应用程序服务器在提交了业务操作事务之后突然崩溃,日志就丢失了。我现在考虑两种方案:保持业务操作和日志持久化事务一致,但日志持久化不直接写数据库或文件,而是利用现有的一些开源的缓存技术(方案一,如EhCache,OSCache),或利用内存数据库(方案二,如ORACLE Berkeley DB) |
|
| 返回顶楼 | |
|
时间:2008-07-15
如果不在同一事务中的确会出现应用正常提交,而日志确没有写入。如果日志非常重要的话的确是很糟糕。
方案一的缓存我觉得行不通; 方案二的内存数据库应该是不错的选择。 |
|
| 返回顶楼 | |
|
时间:2008-07-15
javazhujf 写道 如果不在同一事务中的确会出现应用正常提交,而日志确没有写入。如果日志非常重要的话的确是很糟糕。
方案一的缓存我觉得行不通; 方案二的内存数据库应该是不错的选择。 其实我对缓存和内存数据库都不太熟,正在了解,请问为什么觉得缓存行不通呢?现在的缓存框架应该支持灾难恢复啊。而内存数据库也好,缓存也好,要保证能够灾难恢复,本质上还是要写磁盘,可能是通过某些优化和简化算法提高性能,总比写数据库要好吧,毕竟我在本地缓存下来的数据只是临时的,最终还是要写数据库,正如我前面所说的,通过JMS发送到另外一台专门的日志服务器,由它负责日子的持久化,而在JMS答复成功接收日志信息之前,我需要以一种高性能的方式把日志信息临时保存起来,并保证信息能灾难恢复,因此我才考虑缓存和内存数据库。 这相当于:业务操作与日志本地临时持久化保持同步和事务一致,而日志的真正持久化(日志服务器进行)采用异步方式,这是目前我能想到的一种折中方案。 |
|
| 返回顶楼 | |
|
时间:2008-07-15
写日志写不死你的机器的,我手头的,一天写5G的日志,没事
|
|
| 返回顶楼 | |
|
时间:2008-07-15
williamy 写道 写日志写不死你的机器的,我手头的,一天写5G的日志,没事
我只觉得cache不是做这个用的,之所以青睐内存数据库,是因为使用数据库的话,一是稳定,二可以用夜间batch程序同步内存数据库和其他数据库。 |
|
| 返回顶楼 | |
|
时间:2008-07-15
首先,我们要定义一下,什么叫日志.
我觉得楼上所有的答复,都是作为"通用"日志的解决方案. 我要提醒lz,按照你所说的需求,每个"日志"都要保证记录,并且最好通过数据库事务来保证一旦业务成功提交,日志也提交. 这个描述中的"日志"已经不属于通常意义的系统日志,这个属于业务需求.是业务逻辑的一部分. 如果我是你,我不会把它当成日志来考虑,我会毫不犹豫的象你所说的,把它和其他业务写到同一个事务中. 至于由此引发的额外的系统负担,应该通过其他手段来对整个系统调优. |
|
| 返回顶楼 | |





