背景
我正在使用 Apache 的 NMS 库与 ActiveMq 交谈。每条发送的消息都由生产者标记时间戳,我通过从 中减去时间戳来查看消息延迟DateTime.UtcNow
,我希望看到 0-100 毫秒的延迟,但我看到报告的延迟在 -1000 到 1000 毫秒之间。显然负延迟是没有意义的,所以我最初怀疑系统时钟不同步,但我现在已经独立确认它们是正确的并且在 20 毫秒内。
更多背景
问题
我现在认为这些差异可能是由于 .Net 和 Java 之间处理日期的方式造成的。
- 从 Java 到 .Net 的转换是有损的吗?
- 这些转换能否解释我观察到的较大的负时间跨度?
- 还有什么可以解释时差的吗?
MessageProducer.cs -- 生产者设置 NMSTimestamp
activeMessage.NMSTimestamp = DateTime.UtcNow;
ActiveMqMessage.cs -- NMSTimestamp 转换为 Java 时间并存储在 Message
...
public DateTime NMSTimestamp
{
get { return DateUtils.ToDateTime(Timestamp); }
set
{
Timestamp = DateUtils.ToJavaTimeUtc(value);
if(timeToLive.TotalMilliseconds > 0)
{
Expiration = Timestamp + (long) timeToLive.TotalMilliseconds;
}
}
}
...
Message.cs -- Timestamp 保存有线格式的日期,消息编组器直接设置此值
// ActiveMqMessage extends Message
...
public long Timestamp
{
get { return timestamp; }
set { this.timestamp = value; }
}
...
DateUtils.cs -- 用于执行转换
namespace Apache.NMS.Util
{
public class DateUtils
{
/// <summary>
/// The start of the Windows epoch
/// </summary>
public static readonly DateTime windowsEpoch = new DateTime(1601, 1, 1, 0, 0, 0, 0);
/// <summary>
/// The start of the Java epoch
/// </summary>
public static readonly DateTime javaEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
/// <summary>
/// The difference between the Windows epoch and the Java epoch
/// in milliseconds.
/// </summary>
public static readonly long epochDiff; /* = 1164447360000L; */
static DateUtils()
{
epochDiff = (javaEpoch.ToFileTimeUtc() - windowsEpoch.ToFileTimeUtc())
/ TimeSpan.TicksPerMillisecond;
}
public static long ToJavaTime(DateTime dateTime)
{
return (dateTime.ToFileTime() / TimeSpan.TicksPerMillisecond) - epochDiff;
}
public static DateTime ToDateTime(long javaTime)
{
return DateTime.FromFileTime((javaTime + epochDiff) * TimeSpan.TicksPerMillisecond);
}
public static long ToJavaTimeUtc(DateTime dateTime)
{
return (dateTime.ToFileTimeUtc() / TimeSpan.TicksPerMillisecond) - epochDiff;
}
public static DateTime ToDateTimeUtc(long javaTime)
{
return DateTime.FromFileTimeUtc((javaTime + epochDiff) * TimeSpan.TicksPerMillisecond);
}
}
}
我的代码计算延迟如下
var latency = (DateTime.UtcNow - msg.NMSTimestamp).TotalMilliseconds;