Linux

java中RH Linux和Solaris之間的TCP性能差異?

  • July 7, 2010

在比較 RH Linux 和 Solaris 之間的 java TCP 套接字性能時,我的一項測試是通過使用 java 客戶端發送字元串並從 java echo 伺服器讀取回復來完成的。我測量發送和接收數據所花費的時間(即環回往返)。

該測試執行了 100,000 次(更多的出現給出了類似的結果)。根據我的測試,在具有預設系統和網路設置、相同 JVM 參數(如果有)等的同一台電腦上,Solaris 平均比 RH Linux 快 25/30%。

我不明白這麼大的區別,我是否缺少一些系統/網路參數?

如果有人有興趣執行它,使用的程式碼(客戶端和伺服器)如下所示(必須在命令行中給出出現次數):

import java.io.*;
import java.net.*;
import java.text.*;

public class SocketTest {

public final static String   EOF_STR = "EOF";
public final static String[] st      = {"toto"
   ,"1234567890"
   ,"12345678901234567890"
   ,"123456789012345678901234567890"
   ,"1234567890123456789012345678901234567890"
   ,"12345678901234567890123456789012345678901234567890"
   ,"123456789012345678901234567890123456789012345678901234567890"
};

public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
   double mean = 0.0;
   int port = 30000;
   int times = Integer.parseInt(args[0]); 
   String resultFileName = "res.dat"; 
   new EchoServerSimple(port);        // instanciate and run
   Socket s = new Socket("127.0.0.1", port);        
   s.setTcpNoDelay(true);        
   PrintWriter pwOut = new PrintWriter(s.getOutputStream(), true);
   BufferedReader brIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
   long[] res = new long[times];

   int j = 0;
   for(int i = 0; i < times; i++) {
       if(j >= st.length) j = 0;            
       long t0 = System.nanoTime();
       pwOut.println(st[j++]);
       brIn.readLine();
       res[i] = System.nanoTime() - t0;
       mean += ((double)res[i]) / times;
   }
   pwOut.println(EOF_STR);
   s.close();
   print(res, resultFileName);
   System.out.println("Mean = "+new DecimalFormat("#,##0.00").format(mean));
}

public static void print(long[] res, String output) {
   try {        
       PrintWriter pw;
       pw = new PrintWriter(new File(output));            
       for (long l : res) {
           pw.println(l);
       }
       pw.close();
   } catch (FileNotFoundException e) {
       e.printStackTrace();
   }
}

static class EchoServerSimple implements Runnable {

   private ServerSocket _serverSocket;

   public EchoServerSimple(int port) {
       try { _serverSocket = new ServerSocket(port); } 
       catch (IOException e) { e.printStackTrace(); }
       new Thread(this).start();
   }

   public void run() {
       try {
           Socket clientSocket = _serverSocket.accept();
           clientSocket.setTcpNoDelay(true);    
           PrintWriter pwOut = new PrintWriter(clientSocket.getOutputStream(), true);
           BufferedReader brIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));                
           try {
               while(true) {
                   String s = brIn.readLine();
                   pwOut.println(s);
                   if(s.equals(EOF_STR)) { clientSocket.close(); break;    }
               }
           } catch (Exception e) {
               e.printStackTrace(); 
               try { clientSocket.close(); } catch (IOException e1) { e1.printStackTrace(); }
           }
       } catch (IOException e) {e.printStackTrace(); }
   }
 }
}

我在單個 2.3GHz 雙核 Nehalem 上為兩個作業系統使用 JRE 1.6.0_18。2 OS ar Solaris 10 和 RH Linux 5.4 與 RT Kernel 2.6.24.7。

非常感謝。

在稱為“TCP Fusion”的 Solaris 中,這意味著兩個本地 TCP 端點將被“融合”。因此,它們將完全繞過 TCP 數據路徑。

嘗試禁用它並再次執行測試:

# echo do_tcp_fusion/W 0 | mdb -kw
do_tcp_fusion:0x1 = 0x0

您可能應該嘗試創建一個盡可能模擬您的生產的測試環境。這可能意味著使用網路適配器建立一個真實的網路。

如果你想玩連接限製或其他復雜的網路情況,我建議你在兩個端點之間放置一個 FreeBSD 盒子,然後玩 ipfw/dummynet 的 pf/altq。

引用自:https://serverfault.com/questions/157731