开发者

How to optimize SOA requests in HPC

I want to use HPC to do some simulations, I'm going to use SOA. I have following code from some sample 开发者_运维知识库materials, I modified it (I added this first for). Currently I stumbled upon problem of optimization / poor performance. This basic sample do nothing expect querying service method, this method return value it gets in parameter. However my example is slow. I have 60 computers with 4 core processors and 1Gb network. First phase of sending messages takes something about 2 seconds and then I have to wait another 7 seconds for return values. All values come leas or more at the same time. Another problem I have is that I cannot re-use session object, that is why this first for is outside using I want to put it inside using, but then I get time out, or information that BrokerClient is ended.

Can I reuse BrokerClient or DurableSession object.

How can I speed up this whole process of message passing ?

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();
    }
  }
}

Second version with Session instead of DurableSession, which is working better, but I have problem with Session reuse:

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();
}

I get exception during second run of EndRequest: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.


  1. Don't use DurableSession for computations where the indivdual requests are shorter than about 30 seconds. A DurableSession will be backed by an MSMQ queue in the broker. Your requests and responses may be round-tripped to disk; this will cause performance problems if your amount of computation per request is small. You should use Session instead.
  2. In general, for performance reasons, don't use DurableSession unless you absolutely need the durable behavior in the broker. In this case, since you are calling GetResponses immediately after SendRequests, Session will work fine for you.
  3. You can reuse a Session or DurableSession object to create any number of BrokerClient objects, as long you haven't called Session.Close.
  4. If it's important to process the responses in parallel on the client side, use BrokerClient.SetResponseHandler to set a callback function which will handle responses asynchronously (rather than use client.GetResponses, which handles them synchronously). Look at the HelloWorldR2 sample code for details.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜