使用mina框架
第一次写博客,也不知道怎么写好,就简单说说我使用mina框架的时候存在的问题以及解决办法吧。
第一次简单的使用mina框架,业务也不难,可是每当socket连接增多,就会造成内存和cpu使用大幅度地增长,整个服务速度变慢,http请求也变慢了。而且内存下降速度极慢。重启tomcat后又恢复正常。
后来发现是exceptionCaught、sessionClosed和sessionIdle方法中没有把session关闭,造成了卡顿问题。
mina的配置,端口绑定以及过滤器等配置
/**
* Created by JR on 2017/5/28.
*/
public class MinaServer implements ServletContextListener, HttpSessionListener {
private static NioSocketAcceptor acceptor;
private static final int port = 8990;
public void sessionCreated(HttpSessionEvent se) {
}
public void sessionDestroyed(HttpSessionEvent se) {
}
// 停止MINA服务
public void contextDestroyed(ServletContextEvent sce) {
try {
MinaServer.acceptor.unbind();
MinaServer.acceptor.dispose();
} catch (Exception e) {
}
}
// 启动MINA服务
public void contextInitialized(ServletContextEvent sce) {
try {
// 创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
// 设置读取数据的缓冲区大小
acceptor.getSessionConfig().setReadBufferSize(1024);
// 读写通道10秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
// 添加逻辑处理器
acceptor.setHandler(new MyServerHandler());
// 绑定端口
try {
acceptor.bind(new InetSocketAddress(port));
} catch (Exception e) {
}
System.out.println("Socket服务端启动成功,端口号为:" + port);
} catch (Exception e) {
System.out.println("Socket服务端启动异常:" + e);
}
}
}
下面代码才是重点,必须要在exceptionCaught、sessionClosed和sessionIdle方法中手动调用session.close()方法,或者继承父类的方法。
/**
* Created by JR on 2017/5/28.
*/
public class MyServerHandler extends IoHandlerAdapter {
private static long procidTemp = 0;
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
//业务处理 代码省略
String s = message.toString();
session.write(message);
// session.closeOnFlush();
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
LogUtil.addProclog("exceptionCaught");
LogUtil.addProclog("异常信息"+cause);
if(session!=null){
session.close(true);
LogUtil.addProclog("关闭连接");
}
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
super.messageSent(session,message);
}
@Override
public void inputClosed(IoSession ioSession) throws Exception {
super.inputClosed(ioSession);
}
@Override
public void sessionClosed(IoSession session) throws Exception {
super.sessionClosed(session);
}
@Override
public void sessionCreated(IoSession session) throws Exception {
super.sessionCreated(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
super.sessionIdle(session, status);
session.close(true);
}
@Override
public void sessionOpened(IoSession session) throws Exception {
super.sessionOpened(session);
}
}
总结
测试时,只是连了3个socket而没有释放,服务器内存已经增加了600m!当时觉得mina不至于这么鸡肋,即使不释放连接也不会造成占用这么多资源。所以我觉得,应该是当空闲,或者session将要关闭时,会调用close方法,可是调用后发现session还是没关闭,所以一直循环调用,造成死循环了,才会占用这么多资源。所以解决办法要记得在适当的时候把session关闭掉。