Linux
java中RH Linux和Solaris之間的TCP性能差異?
在比較 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。