我正在尝试编写一个Java代理隧道程序,我需要一个专家建议如何使用最好和最快的流来进行通信。
我已经实现了基本的功能,一切都很好。唯一的问题是交流的速度或性能。我的HTTP代理系统由运行在远程服务器上的服务器程序和运行在本地计算机上的客户端程序组成。到目前为止,该项目如下所示:
Listener.java :
/**
* Listens and accepts connection requests from the browser
*/
ServerSocket listener = null;
try {
listener = new ServerSocket(port, 128);
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
ExecutorService executor = Executors.newCachedThreadPool();
Socket connection;
while (!shutdown) {
try {
connection = listener.accept();
executor.execute(new ProxyTunnel(connection));
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}ProxyTunnel.java :
try {
byte[] buffer = new byte[8192]; // 8-KB buffer
InputStream browserInput = browser.getInputStream();
OutputStream browserOutput = browser.getOutputStream();
// Reading browser request ...
StringBuilder request = new StringBuilder(2048);
do {
int read = browserInput.read(buffer);
logger.log(read + " bytes read from browser.");
if (read > 0) {
request.append(new String(buffer, 0, read));
}
} while (browserInput.available() > 0 && read > 0);
// Connecting to proxy server ...
Socket server = new Socket(SERVER_IP, SERVER_PORT);
server.setSoTimeout(5000); // Setting 5 sec read timeout
OutputStream serverOutput = server.getOutputStream();
InputStream serverInput = server.getInputStream();
// Sending request to server ...
serverOutput.write(request.toString().getBytes());
serverOutput.flush();
// Waiting for server response ...
StringBuilder response = new StringBuilder(16384);
do {
try {
read = serverInput.read(buffer);
} catch (SocketTimeoutException ex) {
break; // Timeout!
}
if (read > 0) {
// Send response to browser.");
response.append(new String(buffer, 0, read));
browserOutput.write(buffer, 0, read);
browserOutput.flush();
}
} while (read > 0);
// Closing connections ...
server.close();
} catch (IOException ex) {
ex.printStackTrace(System.err);
} finally {
try {
browser.close();
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}服务器程序使用类似的方式,并将HTTP请求发送到目标服务器(例如www.stackoverflow.com),并将响应转发给客户端程序,其中客户端程序将响应转发给本地浏览器。
BufferedInputSream和BufferedOutputStream )是否会改善通信性能?java.nio通道和缓冲区,而不是使用java.net套接字和java.io流,我会得到任何性能改进吗?发布于 2012-08-19 08:39:55
不要自己动手
建议0:有大量的代理服务器,更可伸缩,更稳定和成熟。你真的需要自己写吗?
不要使用StringBuilder/String来缓冲请求
byte[] buffer = new byte[8192]; // 8-KB buffer
//...
browserInput.read(buffer);
//...
request.append(new String(buffer, 0, read));
//...
serverOutput.write(request.toString().getBytes());这是有缺陷的,原因有几个:
String并返回到byte[]后将出现格式错误,请参见:字符串、byte[]和压缩不要使用Executors.newCachedThreadPool()
这个池可以无限增长,在高峰期间创建数千个线程。本质上,每个连接创建一个线程(除了池重用空闲线程,但如果没有可用,则创建新线程)。考虑一下Executors.newFixedThreadPool(100) -100-200个线程在大多数情况下应该足够了.在此基础上,您很可能只需要在上下文切换中消耗CPU,而不需要做大量工作。不要害怕潜伏期,缩小范围。
使用非阻塞奈蒂堆栈
这给了我们最后的建议。完全掉落阻塞插座。它们很方便,但是由于每个连接线程的需求,它们的扩展性不太好。占用堆栈的内存太多,用于上下文切换的CPU太多。netty很棒,它为NIO构建了强大的抽象。
查看例句,它们包括HTTP /服务器代码。有一点学习曲线,但您可以预期性能增长几个数量级。
https://stackoverflow.com/questions/12025184
复制相似问题