Posted on 2009-10-09 14:08
dennis 閱讀(3130)
評論(2) 編輯 收藏 所屬分類:
java
采用的是
jboss netty的benchmark,環
境是兩臺linux機器,都是4核16G內存以及2.6內核,網絡環境是公司內網,帶寬是1Gbps
,JDK1.6.0_07。對比的是
mina 2.0M6和
yanf4j 1.0-stable,兩者都在壓到16K,5000并發的時候客戶端退出,因此后面給出的圖有個16K的在5000并發為0,事實上只是幾個連接失敗,但是benchmark client就忽略了這個數據。實際過程還測試了1萬并發連接的情況,但是由于測試客戶端很容易退出,因此最后還是選定最大并發5000。注意,并非mina和yanf4j無法支撐1萬個連接,而是benchmark client本身的處理,再加上內核tcp參數沒有調整造成的。
首先看源碼,mina的Echo Server:
package org.jboss.netty.benchmark.echo.server;
import java.net.InetSocketAddress;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.jboss.netty.benchmark.echo.Constant;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (tlee@redhat.com)
*
* @version $Rev: 394 $, $Date: 2008-10-03 12:55:27 +0800 (星期五, 03 十月 2008) $
*
*/
public class MINA {
public static void main(String[] args) throws Exception {
boolean threadPoolDisabled = args.length > 0 && args[0].equals("nothreadpool");
SocketAcceptor acceptor = new NioSocketAcceptor(Runtime.getRuntime().availableProcessors());
acceptor.getSessionConfig().setMinReadBufferSize(Constant.MIN_READ_BUFFER_SIZE);
acceptor.getSessionConfig().setReadBufferSize(Constant.INITIAL_READ_BUFFER_SIZE);
acceptor.getSessionConfig().setMaxReadBufferSize(Constant.MAX_READ_BUFFER_SIZE);
acceptor.getSessionConfig().setThroughputCalculationInterval(0);
acceptor.getSessionConfig().setTcpNoDelay(true);
acceptor.setDefaultLocalAddress(new InetSocketAddress(Constant.PORT));
if (!threadPoolDisabled) {
// Throttling has been disabled because it causes a dead lock.
// Also, it doesn't have per-channel memory limit.
acceptor.getFilterChain().addLast(
"executor",
new ExecutorFilter(
Constant.THREAD_POOL_SIZE, Constant.THREAD_POOL_SIZE));
}
acceptor.setHandler(new EchoHandler());
acceptor.bind();
System.out.println("MINA EchoServer is ready to serve at port " + Constant.PORT + ".");
System.out.println("Enter 'ant benchmark' on the client side to begin.");
System.out.println("Thread pool: " + (threadPoolDisabled? "DISABLED" : "ENABLED"));
}
private static class EchoHandler extends IoHandlerAdapter {
EchoHandler() {
super();
}
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
session.write(((IoBuffer) message).duplicate());
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
session.close();
}
}
}
再看Yanf4j的Echo Server,沒有多大區別:
package org.jboss.netty.benchmark.echo.server;
import java.nio.ByteBuffer;
import org.jboss.netty.benchmark.echo.Constant;
import com.google.code.yanf4j.config.Configuration;
import com.google.code.yanf4j.core.Session;
import com.google.code.yanf4j.core.impl.HandlerAdapter;
import com.google.code.yanf4j.core.impl.StandardSocketOption;
import com.google.code.yanf4j.nio.TCPController;
public class Yanf4j {
public static void main(String[] args) throws Exception {
boolean threadPoolDisabled = args.length > 0
&& args[0].equals("nothreadpool");
Configuration configuration = new Configuration();
configuration.setCheckSessionTimeoutInterval(0);
configuration.setSessionIdleTimeout(0);
configuration
.setSessionReadBufferSize(Constant.INITIAL_READ_BUFFER_SIZE);
TCPController controller = new TCPController(configuration);
controller.setSocketOption(StandardSocketOption.SO_REUSEADDR, true);
controller.setSocketOption(StandardSocketOption.TCP_NODELAY, true);
controller.setHandler(new EchoHandler());
if (!threadPoolDisabled) {
controller.setReadThreadCount(Constant.THREAD_POOL_SIZE);
}
controller.bind(Constant.PORT);
System.out.println("Yanf4j EchoServer is ready to serve at port "
+ Constant.PORT + ".");
System.out
.println("Enter 'ant benchmark' on the client side to begin.");
System.out.println("Thread pool: "
+ (threadPoolDisabled ? "DISABLED" : "ENABLED"));
}
static class EchoHandler extends HandlerAdapter {
@Override
public void onMessageReceived(final Session session, final Object msg) {
session.write(((ByteBuffer) msg).duplicate());
}
@Override
public void onExceptionCaught(Session session, Throwable t) {
session.close();
}
}
}
兩者都啟用線程池(16個線程),開啟TCP_NODELAY選項,Client采用SYNC模式,壓測結果如下(僅供參考),分別是數據大小為128、1K、4K和16K情況下,隨著并發client上升吞吐量的對比圖:
系統的資源消耗來看,Mina的load相對偏高。