如何在HPC中优化SOA请求
本文关键字:优化 SOA 请求 HPC | 更新日期: 2023-09-27 18:03:35
我想用HPC做一些模拟,我打算用SOA。我有以下代码从一些样本材料,我修改了它(我首先添加了这个)。目前我偶然发现了优化/性能差的问题。这个基本示例除了查询服务方法之外什么都不做,该方法返回它在参数中获得的值。然而我的例子是缓慢的。我有60台4核处理器和1Gb网络的电脑。发送消息的第一阶段需要大约2秒,然后我必须等待另外7秒的返回值。所有值至少在同一时间出现。我遇到的另一个问题是,我不能重用会话对象,这就是为什么这个第一个for是外部使用,我想把它放在内部使用,但后来我得到超时,或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();
}
}
}
第二个版本与会话而不是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时得到异常:服务器没有提供有意义的回复;这可能是由于合约不匹配、会话过早关闭或内部服务器错误造成的。
- 对于单个请求小于30秒的计算,不要使用
DurableSession
。DurableSession
将由代理中的MSMQ队列提供支持。您的请求和响应可能会被传送到磁盘;如果每个请求的计算量很小,这将导致性能问题。你应该用Session
代替。 一般来说,出于性能原因,除非您绝对需要代理中的持久行为,否则不要使用 - 你可以重用
Session
或DurableSession
对象来创建任意数量的BrokerClient
对象,只要你没有调用Session.Close
。 - 如果在客户端并行处理响应很重要,使用
BrokerClient.SetResponseHandler
设置一个回调函数,它将异步处理响应(而不是使用client.GetResponses
,它将同步处理它们)。查看HelloWorldR2
示例代码了解详细信息。
DurableSession
。在这种情况下,由于您在SendRequests
之后立即调用GetResponses
,因此Session
将为您工作。