日志服务器,那游戏服务器为实例,重要的数据库服务器,游戏服务器,网关服务器...往往不在意日志服务器,而通常情况下,日志简单的通过log4j,c下的log4c,cpp下的log4cpp等日志工具,当然,这类日志工具是主流的开源框架,性能,功能面都不错,但如果,我们需要记录几乎每个玩家,没个操作,那么这类在应用程序中添加的日志记录将会消耗大量系统资源,导致服务器卡慢.顾,分布式日志服务器在某些项目架构下非常有意义.
我的分布式服务器,分为3个版本,c语言版本,原生java nio版本,以及依赖mina2框架实现,由于mina2框架的如日中天,相信,这篇文章对于java编程爱好者有一定帮助.
请看源码:
IoHandler的编写.log4j记录错误等日志,而LogWriter为真正的高频度,大数据日志记录工具.
package cn.vicky.mina.logserver;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author Vicky.H
*/
public class LogIoHandler implements IoHandler {
private static final Logger LOG = LoggerFactory.getLogger(LogIoHandler.class);
private Set<IoSession> sessions = Collections.synchronizedSet(new HashSet<IoSession>(10));
// 日志写入器
private LogWriter logWriter;
public LogIoHandler(LogWriter logWriter) {
this.logWriter = logWriter;
}
public void sessionCreated(IoSession session) throws Exception {
// Do nothing...
}
public void sessionOpened(IoSession session) throws Exception {
sessions.add(session);
}
public void sessionClosed(IoSession session) throws Exception {
sessions.remove(session);
}
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
// Do nothing...
}
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
LOG.error("exceptionCaught:", cause);
}
public void messageReceived(IoSession session, Object message) throws Exception {
if (message instanceof IoBuffer) { // 确认数据类型
logWriter.addLog((IoBuffer) message);
}
}
public void messageSent(IoSession session, Object message) throws Exception {
// Do nothing...
}
}
LogWriter 其核心思想是,通过直接缓存区,以及缓存区交换区方式实现数据存储以及写入文件的高性能,高并发,并且通过5分钟左右的写入文件形式,在对日志时间要求不是非常精确下,可以直接通过日志文件名称方式,获得日志范围,可以精简日志文件大小,减少性能消耗.至于此处采用小文件方式记录日志,还有个原因就是方便数据统计.我在日志处理方面,没有编写额外的程序,通过正则表达式等方式拆解,而是通过linux shell命令拆解文件
package cn.vicky.mina.logserver;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DateFormat;
import java.text.SimpleDateF