2011-07-26 97 views
0

我想使用HPC做一些模擬,我將使用SOA。我從一些示例材料中獲得了以下代碼,我對其進行了修改(我首先添加了這個代碼)。目前我偶然發現優化/性能差的問題。這個基本的示例沒有期望查詢服務方法,這個方法在參數中返回值。然而我的例子很慢。我有60臺帶有4個核心處理器和1Gb網絡的電腦。發送消息的第一階段需要約2秒的時間,然後我必須再等待7秒才能返回值。所有的價值都會同時降低或更多。另一個問題是我無法重新使用會話對象,這就是爲什麼這首先是外部使用,我想把它放在內部使用,但是我得到超時或BrokerClient結束的信息。如何在HPC中優化SOA請求

我可以重用BrokerClient或DurableSession對象嗎?

如何加快消息傳遞的整個過程?

static void Main(string[] args) 
{ 
    const string headnode = "Head-Node.hpcCluster.edu.edu"; 
    const string serviceName = "EchoService"; 
    const int numRequests = 1000; 
    SessionStartInfo info = new SessionStartInfo(headnode, serviceName); 
    for (int j = 0; j < 100; j++) 
    { 
    using (DurableSession session = DurableSession.CreateSession(info)) 
    { 
     Console.WriteLine("done session id = {0}", session.Id); 
     NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport); 
     using (BrokerClient<IService1> client = new BrokerClient<IService1>(session, binding)) 
     { 
     for (int i = 0; i < numRequests; i++) 
     { 
      EchoRequest request = new EchoRequest("hello world!"); 
      client.SendRequest<EchoRequest>(request, i); 
     } 
     client.EndRequests(); 
     foreach (var response in client.GetResponses<EchoResponse>()) 
     { 
      try 
      { 
      string reply = response.Result.EchoResult; 
      Console.WriteLine("\tReceived response for request {0}: {1}", response.GetUserData<int>(), reply); 
      } 
      catch (Exception ex) 
      { 
      } 
     } 

     } 
     session.Close(); 
    } 
    } 
} 

第二個版本與會議代替DurableSession,這是更好的工作,但我有問題,會話重用:

using (Session session = Session.CreateSession(info)) 
{ 

for (int i = 0; i < 100; i++) 
{ 
    count = 0; 

    Console.WriteLine("done session id = {0}", session.Id); 
    NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport); 

    using (BrokerClient<IService1> client = new BrokerClient<IService1>(session, binding)) 
    { 
      //set getresponse handler 
      client.SetResponseHandler<EchoResponse>((item) => 
      { 
       try 
       { 
        Console.WriteLine("\tReceived response for request {0}: {1}", 
        item.GetUserData<int>(), item.Result.EchoResult); 
       } 
       catch (SessionException ex) 
       { 
        Console.WriteLine("SessionException while getting responses in callback: {0}", ex.Message); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Exception while getting responses in callback: {0}", ex.Message); 
       } 

       if (Interlocked.Increment(ref count) == numRequests) 
        done.Set(); 

      }); 

     // start to send requests 
     Console.Write("Sending {0} requests...", numRequests); 

     for (int j = 0; j < numRequests; j++) 
     { 
      EchoRequest request = new EchoRequest("hello world!"); 
      client.SendRequest<EchoRequest>(request, i); 
     } 
      client.EndRequests(); 

     Console.WriteLine("done"); 
     Console.WriteLine("Retrieving responses..."); 

     // Main thread block here waiting for the retrieval process 
     // to complete. As the thread that receives the "numRequests"-th 
     // responses does a Set() on the event, "done.WaitOne()" will pop 
     done.WaitOne(); 
     Console.WriteLine("Done retrieving {0} responses", numRequests); 
    } 
} 
// Close connections and delete messages stored in the system 
session.Close(); 
} 

我EndRequest的第二次運行時得到的異常:服務器未提供有意義的回覆這可能是由於合同不匹配,會話過早關閉或內部服務器錯誤造成的。

+0

您似乎在說您修改了示例代碼導致了您所看到的問題? –

+0

您使用多少個代理節點? –

+0

@Mitch Broker節點,只有一個它是頭節點。也許我的修改引入了這個問題我認爲有一種方法可以以更有效的方式來實現,但我找不到它。當我首先將1放入循環初始化時,發送任務和檢索也需要一些時間。 – Darqer

回答

4
  1. 請勿使用DurableSession進行計算,其中個別請求短於約30秒。 A DurableSession將由代理中的MSMQ隊列支持。您的請求和響應可能會被輪詢到磁盤;如果您的每個請求的計算量很小,這會導致性能問題。您應該改用Session
  2. 一般而言,出於性能原因,請勿使用DurableSession,除非您絕對需要代理中的耐用行爲。在這種情況下,因爲您在SendRequests之後立即致電GetResponses,所以Session將爲您正常工作。
  3. 只要您還沒有調用Session.Close,您可以重複使用SessionDurableSession對象來創建任意數量的BrokerClient對象。
  4. 如果在客戶端並行處理響應非常重要,請使用BrokerClient.SetResponseHandler來設置將異步處理響應的回調函數(而不是使用client.GetResponses,它們會同步處理它們)。詳細信息請參見HelloWorldR2示例代碼。
+0

非常感謝。但我仍然有問題。我如何重用會話。我在Session對象上創建BrokerClient,然後發送請求,最後我必須使用EndRequest,這似乎關閉了整個會話對象,因爲在下一個循環中,我在此Session對象上創建另一個BrokerClient, EndRequest方法? – Darqer

+0

您是否對「for」和「using」語句重新排序?在使用結束時,會話將被關閉。 – joXn

+0

我將當前的代碼放入我的問題中。 – Darqer