如何优化 HPC 中的 SOA 请求

发布于 2024-11-26 03:29:09 字数 3800 浏览 0 评论 0原文

我想使用 HPC 来做一些模拟,我将使用 SOA。我有一些示例材料中的以下代码,我对其进行了修改(我首先添加了此代码)。目前我偶然发现了优化/性能不佳的问题。这个基本示例不执行任何查询服务方法的操作,该方法返回在参数中获取的值。然而我的例子很慢。我有 60 台带有 4 核处理器和 1Gb 网络的计算机。发送消息的第一阶段大约需要 2 秒,然后我必须再等待 7 秒才能返回值。所有值同时出现或更多。我遇到的另一个问题是我无法重用会话对象,这就是为什么这第一个 for 是外部 using 我想将它放在 using 内部,但后来我超时,或者 BrokerClient 已结束的信息。

我可以重用 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();
    }
  }
}

第二个版本使用 Session 而不是 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 期间出现异常:服务器没有提供有意义的回复;这可能是由合同不匹配、会话过早关闭或内部服务器错误引起的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独夜无伴 2024-12-03 03:29:09
  1. 不要使用 DurableSession 进行单个请求短于 30 秒左右的计算。 DurableSession 将由代理中的 MSMQ 队列支持。您的请求和响应可能会往返到磁盘;如果每个请求的计算量很小,这将导致性能问题。您应该使用 Session 来代替。
  2. 一般来说,出于性能原因,不要使用 DurableSession ,除非您绝对需要代理中的持久行为。在这种情况下,由于您在 SendRequests 之后立即调用 GetResponses,因此 Session 可以正常工作。
  3. 只要您没有调用 Session.Close,您就可以重复使用 SessionDurableSession 对象来创建任意数量的 BrokerClient 对象
  4. 如果在客户端并行处理响应很重要,请使用 BrokerClient.SetResponseHandler 设置异步处理响应的回调函数(而不是使用 client.GetResponses),它同步处理它们)。有关详细信息,请参阅 HelloWorldR2 示例代码。
  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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文