Log4js多进程陷阱与避免

基于log4js 0.6.14版本

Log4js总共三篇博客

《Log4js原理解析》http://write.blog.csdn.net/postedit/42844085

《Log4js配置详解》http://blog.csdn.net/hfty290/article/details/42843737

《Log4js多进程陷阱与避免》http://blog.csdn.net/hfty290/article/details/42843303

在node之中由于单个进程内存存在1.4GB的上限,因此在一些大型的系统中,通常使用cluster的方式来运行。在cluster环境,也就是多进程环境中,在使用log4js时其实有一个陷阱,可能很多人都遇见过,让人错愕。

在单进程环境中大家会使用file或者datefile类型的Appender实例来写日志,并且为了日志的自动清除还设置了滚动方式,按照文件大小或者日期进行滚动。但是这两种类型的Appender在达到滚动阈值时,先进性rename,然后创建一个新的文件,把后面的内容写入到新的文件中。

例如:在datefile按照天进行滚动的环境中,日志文件名为cheese.log

rename cheese.log cheese.log.2015-01-17
create file cheese.log
write cheese.log

在单进程环境中,这完全没有问题,但是在多进程环境就会有问题。问题就出在每个进程都要执行上面的rename与create操作。在多进程写同一个文件时,实际上只要有一个进程执行rename与create操作就行了。

例如:

<span style="font-size:12px;">进程A先被触发,执行换天备份日志操作:
rename cheese.log cheese.log.2015-01-17
create file cheese.log
write cheese.log
在后面的某个时间,进程B也被触发了,再次执行换天备份日志操作:
rename cheese.log cheese.log.2015-01-17
create file cheese.log
write cheese.log</span><span style="font-size: 11pt;">
</span>

看出来了吧,在被执行了第二次之后,2015-01-16上的数据其实丢失了,cheese.log.2015-01-17文件内容只是进程A备份到进程B备份,这段时间的日志。现在问题说清楚了,我们来想想解决方案。

问题的关键出在多个进程在不同时候执行了换天备份操作,那么如果能够保证只有一个进程执行换天备份就没问题了。

在log4js中提供了两种这种类型的Appender,分别是clustered与multiprocess,都是在master进程上开启监听,worker进程将日志简单地发送给master,日志的写入备份等操作都有master进程进行。但是这种方式有一个缺点,日志通过网络传输,node是先缓冲到本地数组,然后提供给socket缓冲区,假如网络写入速度比日志写入速度慢,那么以为着进程的内存占用会越来越多,最终可想而知了。

另外一种更好地方式是使用datefile类型的Appender,但是设置alwaysIncludePattern属性为true,也就是说每次写日志直接写在 cheese.log.2015-01-17这样的文件上,换天的时候写到新的日志文件即可。这种方式就去掉了rename日志的过程,从而避免多进程导致的日志rename混乱。

关于clustered、multiprocess、datefile类型的Appender具体配置,请看另一篇博客《log4js配置详解》中“datefile配置”,“multiprocess配置”,“cluster配置”的三个小节。

Log4js总共三篇博客

《Log4js原理解析》http://write.blog.csdn.net/postedit/42844085

《Log4js配置详解》http://blog.csdn.net/hfty290/article/details/42843737

《Log4js多进程陷阱与避免》http://blog.csdn.net/hfty290/article/details/42843303

时间: 2025-01-08 08:12:49

Log4js多进程陷阱与避免的相关文章

Log4js配置详解

基于log4js 0.6.14版本 Log4js总共三篇博客 <Log4js原理解析>http://write.blog.csdn.net/postedit/42844085 <Log4js配置详解>http://blog.csdn.net/hfty290/article/details/42843737 <Log4js多进程陷阱与避免>http://blog.csdn.net/hfty290/article/details/42843303 一.概述 log4js配置

Log4js原理解析

基于log4js 0.6.14版本 Log4js总共三篇博客 <Log4js原理解析>http://write.blog.csdn.net/postedit/42844085 <Log4js配置详解>http://blog.csdn.net/hfty290/article/details/42843737 <Log4js多进程陷阱与避免>http://blog.csdn.net/hfty290/article/details/42843303 一.概述 网络上有不少关于

nodejs之日志管理

开发一个项目时,可以通过控制台输出或者debug来获取到项目的运行信息.当项目上线时,我们就需要通过日志来分析.如同Java的log4j,nodejs中也有相关的log4js.使用过log4j的同学应该对此不会陌生. 1.日志级别 log4js共有6种日志级别,分别为:trace.debug.info.warn.error.fatal.权值从小到大,其初始化代码为: TRACE: new Level(5000, "TRACE"), DEBUG: new Level(10000, &qu

【转】 Android应用内多进程分析和研究

正常情况下,一个apk启动后只会运行在一个进程中,其进程名为AndroidManifest.xml文件中指定的应用包名,所有的基本组件都会在这个进程中运行.但是如果需要将某些组件(如Service.Activity等)运行在单独的进程中,就需要用到Android:process属性了.我们可以为android的基础组件指定process属性来指定它们运行在指定进程中. 有什么好处 一般来说,Android应用多进程有三个好处. 1)我们知道Android系统对每个应用进程的内存占用是有限制的,而

C#:多进程开发,控制进程数量

正在c#程序优化时,如果多线程效果不佳的情况下,也会使用多进程的方案,如下: System.Threading.Tasks.Task task=System.Threading.Tasks.Task.Factory.StartNew( (object mystate) => { Process process = Process.Start("AutoCollectMrMultipleProcess.exe", mystate.ToString()); process.WaitF

多线程和多进程的区别与联系

1.单进程单线程:一个人在一个桌子上吃菜.2.单进程多线程:多个人在同一个桌子上一起吃菜.3.多进程单线程:多个人每个人在自己的桌子上吃菜. 多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了...此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢. 1.对于 Windows 系统来说,[开桌子]的开销很大,因此 Windows 鼓励大家在一个桌子上吃菜.因此 Windows 多线程学习重点

Python有了asyncio和aiohttp在爬虫这类型IO任务中多线程/多进程还有存在的必要吗?

最近正在学习Python中的异步编程,看了一些博客后做了一些小测验:对比asyncio+aiohttp的爬虫和asyncio+aiohttp+concurrent.futures(线程池/进程池)在效率中的差异,注释:在爬虫中我几乎没有使用任何计算性任务,为了探测异步的性能,全部都只是做了网络IO请求,就是说aiohttp把网页get完就程序就done了. 结果发现前者的效率比后者还要高.我询问了另外一位博主,(提供代码的博主没回我信息),他说使用concurrent.futures的话因为我全

多线程还是多进程的选择及区别

对比维度 多进程 多线程 总结 数据共享.同步 数据共享复杂,需要用IPC:数据是分开的,同步简单 因为共享进程数据,数据共享简单,但也是因为这个原因导致同步复杂 各有优势 内存.CPU 占用内存多,切换复杂,CPU利用率低 占用内存少,切换简单,CPU利用率高 线程占优 创建销毁.切换 创建销毁.切换复杂,速度慢 创建销毁.切换简单,速度很快 线程占优 编程.调试 编程简单,调试简单 编程复杂,调试复杂 进程占优 可靠性 进程间不会互相影响 一个线程挂掉将导致整个进程挂掉 进程占优 分布式 适

python 之 多进程

阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiprocessingpython中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情.借助这个包,可以轻松完成从单进程到并发执行的转换.multiprocessin