我会翻译中文。这段内容与编程有关,作者使用 siege 对自己手动构建的文件服务器进行压力测试,对于小文件(小于1KB),它表现得相当好,但是当测试一个1MB文件时,表现并不如预期。
以下是测试小文件的结果:
以下是使用1MB文件进行测试的结果:
当以上述错误终止时,我的文件服务器仍然会旋转固定数量的 SelectionKey,即保持返回固定数量,比如50。
通过以上测试,我发现我的文件服务器最多只能接受50个并发连接,因为在使用小文件运行测试时,我注意到服务器选择1或2个SelectionKeys,而在使用大文件运行时,它每次选择50个。
我尝试增加中的但没有帮助。
问题的原因是什么?
编辑
更多信息:
当测试一个1MB文件时,我注意到以错误终止,并且文件服务器仅接受了198个连接,尽管我指定了1000个并发连接x 10轮(1000 * 10 = 10000)来淹没服务器。
编辑2
以下是测试小文件的结果:
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
当以上述错误终止时,我的文件服务器仍然会旋转固定数量的 SelectionKey,即保持返回固定数量,比如50。
通过以上测试,我发现我的文件服务器最多只能接受50个并发连接,因为在使用小文件运行测试时,我注意到服务器选择1或2个SelectionKeys,而在使用大文件运行时,它每次选择50个。
我尝试增加中的但没有帮助。
问题的原因是什么?
编辑
更多信息:
当测试一个1MB文件时,我注意到以错误终止,并且文件服务器仅接受了198个连接,尽管我指定了1000个并发连接x 10轮(1000 * 10 = 10000)来淹没服务器。
编辑2
我已经使用以下代码(单个类)进行测试,以重现同样的问题,在这段代码中,我只接受连接,不读取或写入,siege
客户端在连接超时之前以连接重置
或断开管道
错误终止。我还注意到选择器只能选择少于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<SelectionKey> 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);
}
}