java nio key_Java NIO Selector可以选择不超过50个SelectionKeys?

我使用

siege对我的手工构建的文件服务器进行压力测试,它适用于小文件(小于1KB),而在使用1MB文件进行测试时,它不能按预期工作.

以下是使用小文件进行测试的结果:

neevek@~$siege -c 1000 -r 10 -b http://127.0.0.1:9090/1KB.txt

** SIEGE 2.71

** Preparing 1000 concurrent users for battle.

The server is now under siege.. done.

Transactions: 10000 hits

Availability: 100.00 %

Elapsed time: 9.17 secs

Data transferred: 3.93 MB

Response time: 0.01 secs

Transaction rate: 1090.51 trans/sec

Throughput: 0.43 MB/sec

Concurrency: 7.29

Successful transactions: 10000

Failed transactions: 0

Longest transaction: 1.17

Shortest transaction: 0.00

以下是使用1MB文件进行测试的结果:

neevek@~$siege -c 1000 -r 10 -b http://127.0.0.1:9090/1MB.txt

** SIEGE 2.71

** Preparing 1000 concurrent users for battle.

The server is now under siege...[error] socket: read error Connection reset by peer sock.c:460: Connection reset by peer

[error] socket: unable to connect sock.c:222: Connection reset by peer

[error] socket: unable to connect sock.c:222: Connection reset by peer

[error] socket: unable to connect sock.c:222: Connection reset by peer

[error] socket: read error Connection reset by peer sock.c:460: Connection reset by peer

[error] socket: unable to connect sock.c:222: Connection reset by peer

[error] socket: read error Connection reset by peer sock.c:460: Connection reset by peer

[error] socket: read error Connection reset by peer sock.c:460: Connection reset by peer

[error] socket: read error Connection reset by peer sock.c:460: Connection reset by peer

[error] socket: read error Connection reset by peer sock.c:460: Connection reset by peer

当siege以上述错误终止时,我的文件服务器仍然使用固定数量的WRITABLE SelectionKey旋转,即Selector.select()保持返回固定数字,比如50.

通过上面的测试,在我看来我的文件服务器不能接受不超过50个并发连接,因为当用小文件运行测试时,我注意到服务器选择1或2个SelectionKeys,当运行大文件时,它选择每次最多50个.

我试图在没有帮助的情况下增加Socket.bind()中的积压.

可能是问题的原因是什么?

编辑

更多信息:

当使用1MB文件进行测试时,我注意到siege以Broken管道错误终止,并且文件服务器只接受了198个连接,尽管我指定了1000个并发连接x 10轮(1000 * 10 = 10000)来充斥服务器.

编辑2

我已经使用以下代码测试(单个类)来重现同样的问题,在这段代码中,我只接受连接,我不读或写,siege客户端终止连接重置或连接超时之前的管道错误.我还注意到Selector只能选择少于1000个键.您可以尝试下面的代码来见证问题.

public class TestNIO implements Runnable {

ServerSocketChannel mServerSocketChannel;

Selector mSelector;

public static void main(String[] args) throws Exception {

new TestNIO().start();

}

public TestNIO () throws Exception {

mSelector = Selector.open();

}

public void start () throws Exception {

mServerSocketChannel = ServerSocketChannel.open();

mServerSocketChannel.configureBlocking(false);

mServerSocketChannel.socket().bind(new InetSocketAddress(9090));

mServerSocketChannel.socket().setSoTimeout(150000);

mServerSocketChannel.register(mSelector, SelectionKey.OP_ACCEPT);

int port = mServerSocketChannel.socket().getLocalPort();

String serverName = "http://" + InetAddress.getLocalHost().getHostName() + ":" + port;

System.out.println("Server start listening on " + serverName);

new Thread(this).start();

}

@Override

public void run() {

try {

Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

while (true) {

int num = mSelector.select();

System.out.println("SELECT = " + num + "/" + mSelector.keys().size());

if (num > 0) {

Iterator keys = mSelector.selectedKeys().iterator();

while (keys.hasNext()) {

final SelectionKey key = keys.next();

if (key.isValid() && key.isAcceptable()) {

accept(key);

}

}

// clear the selected keys

mSelector.selectedKeys().clear();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

private void accept (SelectionKey key) throws IOException {

SocketChannel socketChannel = mServerSocketChannel.accept();

socketChannel.configureBlocking(false);

socketChannel.socket().setSoTimeout(1000000);

socketChannel.socket().setKeepAlive(true);

// since we are connected, we are ready to READ

socketChannel.register(mSelector, SelectionKey.OP_READ);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值