C# WCF 客户端-服务器消息传递/事务优化



我有一个客户端-服务器应用程序,我正在尝试优化。 我构建了一个 psydo 客户端来攻击我的服务器的 API。 我在一个盒子上运行客户端,在另一个盒子上运行服务器。 我试图将两者之间某些事件的时间相关联,其中时间是根据每个本地系统的本地系统时钟记录的。 客户端发送请求并记录该时间。 服务器接收该请求并记录该时间。 服务器正在处理表单/发送响应,记录该时间。 客户端记录它完成接收响应的时间。

最终,我要做的是通过客户端的请求发送和响应接收来衡量通过吞吐量。

我是否通过尝试有意义地关联两个系统上的时钟而错过了什么? 这可能吗? 如果是这样,它是如何完成的?您如何衡量/改进此通量?

目前,我的客户告诉我,我每秒正在为 25+ 个事务执行 19,000 个请求(或平均间隔为 0.04 秒)。 但是服务器上的两个时间戳告诉我我正在处理一个事务,请求接收到响应回复平均在 0.020 秒内(扩展容量 ~ 最大值:50 个事务/秒) 这意味着1/2的开始到结束时间是数据"在线"(归功于Vince Vaughn)。 如果我必须将在线时间视为固定的,并且只能优化服务器周转,这意味着,并且假设我可以将其减少到 0,那么我的最大吞吐量不能大于每秒 50 个事务。 我认为这可以减少到其中的 1/100。 对于一个1G网络来说,只有50个交易/秒似乎非常慢,因为一个数据包只需要通过一个交换机和整个长度约50英尺的电缆。

那么如何关联两个系统时间呢? 你如何衡量这一点?

这是一个非常酷的测试 - 你的技术听起来是一个很好的解决方案。

您是否将日期和时间答案保存在某处? 可能是时差(分别为0.04秒和0.02秒)是由于记录这些日期需要多长时间? 即,例如,如果您保存到数据库,并且由于带有索引的大表等原因,插入/更新可能需要一些时间才能完成?

编辑 我在下面尝试使用在同一台机器上运行的WCF服务器和客户端进行模拟 - 以消除WCF本身可能由于任何原因而变慢。 情况似乎并非如此,所以我只能建议尝试找出事件日志记录是否可能导致延迟,或者您的网络设置是否确实存在一些奇怪的滞后

我的服务器代码:

public interface IServiceWCF
{
[OperationContract]
DateTime TestConnectionSpeed(DateTime messageSentFromClientTime, out DateTime messageReceivedAtServerTime, out int millisecondsBetweenClientSentAndServerReceived);
}
public class ServiceWCF : IServiceWCF
{
public DateTime TestConnectionSpeed(DateTime messageSentFromClientTime, out DateTime messageReceivedAtServerTime, out int millisecondsBetweenClientSentAndServerReceived)
{
messageReceivedAtServerTime = DateTime.Now;
TimeSpan span = messageReceivedAtServerTime - messageSentFromClientTime;
millisecondsBetweenClientSentAndServerReceived = (int)span.TotalMilliseconds;
return DateTime.Now;
}
}   

我的客户端代码

int millisecondsBetweenClientSentAndServerReceived;
DateTime clientSent = DateTime.Now;
DateTime serverReceived;
DateTime serverSent = wcfService.TestConnectionSpeed(clientSent, out serverReceived, out millisecondsBetweenClientSentAndServerReceived);
DateTime responseReceived = DateTime.Now;
TimeSpan span = responseReceived - serverSent;  
int millisecondsBetweenServerSentAndClientReceived = (int)span.TotalMilliseconds;
Console.WriteLine("Message sent from client at {0} - server received {1} milliseconds later at {2} - server response sent at {3} - was received at client {4} milliseconds later at {5}",
clientSent,
millisecondsBetweenClientSentAndServerReceived,
serverReceived,
serverSent,
millisecondsBetweenServerSentAndClientReceived,
responseReceived);

答案大多非常快 - 1 毫秒 - 请参阅示例输出:

Message sent from client at 3/24/2017 3:56:22 PM - server received 1 milliseconds later at 3/24/2017 3:56:22 PM - server response sent at 3/24/2017 3:56:22 PM - was received at client 1 milliseconds later at 3/24/2017 3:56:22 PM

去过那里,这就是我所做的。

让客户端记录请求发送时间并将其发送到服务器。 当服务器收到时,服务器会根据服务器自己的DateTime.Now计算客户端报告的TimeSpan

让服务器记录相对于TimeSpan的时间,或者DateTime.Now.(tsVariable);您可以(稍微*)将服务器视为"客户端"时钟的记录时间。

您需要Subtract差异,因为如果服务器的时钟比客户端的时钟领先一点,则减去差异以使服务器的DateTime.Now更紧密地反映客户端的相对DateTime.Now。 在这种情况下,时间跨度将为 (+) 正值。 如果服务器的时钟比客户端的时钟晚一点,那么 TimeSpan 将为 (-) 负数。 但仍然减去TimeSpan. 这将是所谓的"减去负数",这与添加TimeSpan以捕获服务器的DateTime.Now到相对客户端的DateTime.Now相同。

当响应返回客户端时,让客户端再次记录它自己的时钟,以记录收到的最终响应。 服务器不需要向客户端报告其时间。

*不利的一面是,从客户端首次开发要向服务器报告的内容到服务器收到该报告然后计算TimeSpan之间的勾号,双方都不知道。 但我不得不相信,这并不过分重要,或者至少不是在务实的意义上。

我玩过的另一个场景是让客户端首先获取服务器的时间。 这应该尽可能超快速地提取。 让客户端计算TimeSpan,将其用于记录和向服务器报告,.... 您可能会发现这种程度的努力并不能带来很多好处。

一个高端选项是第三个系统为您记录其他两个系统上的时间,它将不断记录两个系统之间的时差,并且它自己的时钟和/或调整两个系统上的时钟。

最新更新