Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java—用于TCP/HTTP通信的最快流?_Java_Performance_Http_Proxy_Network Programming - Fatal编程技术网

Java—用于TCP/HTTP通信的最快流?

Java—用于TCP/HTTP通信的最快流?,java,performance,http,proxy,network-programming,Java,Performance,Http,Proxy,Network Programming,我正在尝试编写一个JavaHTTP代理隧道程序,我需要专家提供关于通信使用的最佳和最快流的建议 我已经实现了基本功能,一切正常。唯一的问题是通信速度或性能。我的HTTP代理系统由一个运行在远程服务器上的服务器程序和一个运行在本地计算机上的客户端程序组成。到目前为止,该计划如下所示: Listener.java: ProxyTunnel.java: 服务器程序使用类似的方式,将HTTP请求发送到目标服务器(例如www.stackoverflow.com),并将响应转发给客户端程序,客户端程序将

我正在尝试编写一个JavaHTTP代理隧道程序,我需要专家提供关于通信使用的最佳和最快流的建议

我已经实现了基本功能,一切正常。唯一的问题是通信速度或性能。我的HTTP代理系统由一个运行在远程服务器上的服务器程序和一个运行在本地计算机上的客户端程序组成。到目前为止,该计划如下所示:

Listener.java:

ProxyTunnel.java:

服务器程序使用类似的方式,将HTTP请求发送到目标服务器(例如www.stackoverflow.com),并将响应转发给客户端程序,客户端程序将响应转发给本地浏览器

  • 如何提高这些TCP/HTTP通信的性能
  • 使用诸如
    bufferedInputsRAM
    BufferedOutputStream
    之类的缓冲流是否提高了通信性能
  • 如果我使用
    java.nio
    通道和缓冲区,而不是
    java.net
    Sockets和
    java.io
    Stream,我会获得性能改进吗
  • 不要自己做 建议0:现在有很多代理服务器,它们的可扩展性、稳定性和成熟度都要高得多。你真的需要自己写吗

    不要使用
    StringBuilder
    /
    String
    来缓冲请求 这是有缺陷的,原因有几个:

    • 假设您的HTTP调用仅为文本(ASCII),二进制数据在转换为
      字符串
      并返回到
      字节[]
      后将出现格式错误,请参阅:

    • 即使协议是基于文本的,也使用系统的默认编码。我打赌这不是你想要的

    • 最后,最重要的部分:不要缓冲整个请求。从传入请求中读取数据块,并在一次迭代中将其立即转发到目标服务器。绝对不需要额外的内存开销和延迟。在收到几个字节后,立即发送它们并忘记它们

    不要使用 这个池可以无限增长,在峰值期间创建数千个线程。基本上,每个连接创建一个线程(除了池重用空闲线程,但如果没有可用线程,则创建新线程)。在大多数情况下,考虑100-200线程应该足够了。除此之外,您很可能会在上下文切换中几乎不消耗CPU,而不会做很多工作。不要害怕延迟,扩展

    使用非阻塞堆栈 这就引出了最后的建议。完全放下阻塞插座。它们很方便,但由于每个连接都需要线程,所以不能很好地扩展。太多的内存用于保存堆栈,太多的CPU用于上下文切换。netty很棒,它在NIO上构建了强大的抽象


    请检查,它们包括HTTP客户机/服务器代码。有一点学习曲线,但你可以预期绩效增长几个数量级。

    愚蠢的问题:你为什么要重新发明轮子?@Michael-O:当然是为了学习和教育目的!侮辱别人之前最好三思而后行!很好的观点。我肯定会在我的节目中考虑这些。但是你没有回答我的其他问题。我的意思是最后的第二和第三个问题。@SeyedMohammad:对。对于#2:一般来说,是的,只要您不缓冲已经缓冲的流。但在您已经以块的形式读取数据的情况下,缓冲只会稍微增加内存消耗,并可能使代码变慢。顺便说一下-非常有用!广告#3-内蒂是建立在NIO之上的,我想我很清楚这是正确的选择。裸NIO通道通常会更快,但您必须正确使用它们。
    /**
     * 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);
        }
    }
    
    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);
        }
    }
    
    byte[] buffer = new byte[8192];  // 8-KB buffer
    //...
    browserInput.read(buffer);
    //...
    request.append(new String(buffer, 0, read));
    //...
    serverOutput.write(request.toString().getBytes());