Posted on 2009-10-09 14:08
dennis 閱讀(3130)
評(píng)論(2) 編輯 收藏 所屬分類:
java
采用的是
jboss netty的benchmark,環(huán)
境是兩臺(tái)linux機(jī)器,都是4核16G內(nèi)存以及2.6內(nèi)核,網(wǎng)絡(luò)環(huán)境是公司內(nèi)網(wǎng),帶寬是1Gbps
,JDK1.6.0_07。對(duì)比的是
mina 2.0M6和
yanf4j 1.0-stable,兩者都在壓到16K,5000并發(fā)的時(shí)候客戶端退出,因此后面給出的圖有個(gè)16K的在5000并發(fā)為0,事實(shí)上只是幾個(gè)連接失敗,但是benchmark client就忽略了這個(gè)數(shù)據(jù)。實(shí)際過(guò)程還測(cè)試了1萬(wàn)并發(fā)連接的情況,但是由于測(cè)試客戶端很容易退出,因此最后還是選定最大并發(fā)5000。注意,并非mina和yanf4j無(wú)法支撐1萬(wàn)個(gè)連接,而是benchmark client本身的處理,再加上內(nèi)核tcp參數(shù)沒(méi)有調(diào)整造成的。
首先看源碼,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,沒(méi)有多大區(qū)別:
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個(gè)線程),開(kāi)啟TCP_NODELAY選項(xiàng),Client采用SYNC模式,壓測(cè)結(jié)果如下(僅供參考),分別是數(shù)據(jù)大小為128、1K、4K和16K情況下,隨著并發(fā)client上升吞吐量的對(duì)比圖:
系統(tǒng)的資源消耗來(lái)看,Mina的load相對(duì)偏高。