Как оптимизировать SOA-запросы в HPC - PullRequest
0 голосов
/ 26 июля 2011

Я хочу использовать HPC для моделирования, я собираюсь использовать SOA.У меня есть следующий код из некоторых примеров материалов, я изменил его (я сначала добавил это для).В настоящее время я столкнулся с проблемой оптимизации / низкой производительности.В этом базовом примере ничего не ожидается при запросе метода сервиса, этот метод возвращает значение, которое получает в параметре.Однако мой пример медленный.У меня 60 компьютеров с 4-х ядерными процессорами и сетью 1 Гб.Первый этап отправки сообщений занимает около 2 секунд, а затем мне нужно подождать еще 7 секунд для возврата значений.Все значения приходят как минимум, так и одновременно.Другая проблема, с которой я сталкиваюсь, заключается в том, что я не могу повторно использовать объект сеанса, поэтому сначала используется внешнее использование, я хочу поместить его в использование, но затем получаю время или информацию о том, что 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, которая работает лучше, но у меня проблема с повторным использованием Session:

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: сервер не дал значимого ответа;это может быть вызвано несоответствием контракта, преждевременным завершением сеанса или внутренней ошибкой сервера.

1 Ответ

4 голосов
/ 02 августа 2011
  1. Не используйте DurableSession для вычислений, где индивидуальные запросы короче, чем около 30 секунд.DurableSession будет поддерживаться очередью MSMQ в посреднике.Ваши запросы и ответы могут быть закачаны на диск;это приведет к проблемам с производительностью, если количество вычислений на один запрос невелико.Вы должны использовать Session вместо этого.
  2. Как правило, из соображений производительности не используйте DurableSession, если только вам абсолютно не нужно долговременное поведение в брокере.В этом случае, поскольку вы звоните GetResponses сразу после SendRequests, Session будет работать нормально для вас.
  3. Вы можете повторно использовать объект Session или DurableSession для создания любого числа BrokerClient объектов, если вы не вызывали Session.Close.
  4. Если важно обрабатывать ответы параллельно на стороне клиента, используйте BrokerClient.SetResponseHandler для установки функции обратного вызова, которая будет обрабатывать ответы асинхронно (вместо использования client.GetResponses, который обрабатывает их синхронно).Смотрите пример кода HelloWorldR2.
...