节点的process.hrtime
如下:
假设有一个仅附加事件流应该保留(在数据库或文件中)。
node
的{{1}}作为增量ID有多坏?hrtime
就像单线程事件循环一样,因此在单进程的范围内不会有冲突或时间戳混乱吗?是否有任何使用node
进行此类引用的开源项目?
例如,系统可能不是在很高的吞吐量下运行,但考虑到高性能的CPU,一个动作可能会导致多个事件,因此很有可能在处理该动作的范围内多次调用hrtime
,将导致生成相同的毫秒级时间戳。
答案 0 :(得分:0)
基本上,在Linux上,node
的{{1}}深入到:
libuv
使用libuv
提供clock_gettime(CLOCK_MONOTONIC, ...)
。寻找hrtime
可以找到许多关于SO的答案。
按照手册:
CLOCK_MONOTONIC 由于POSIX所述,“过去的一些未指定时间”,因此无法设置并表示单调时间的时钟。在Linux上,该点对应于系统自启动以来已运行的秒数。 CLOCK_MONOTONIC时钟不受系统时间的不连续跳跃影响(例如,如果系统管理员手动更改时钟),但会受到adjtime(3)和NTP执行的增量调整的影响。此时钟不计算系统挂起的时间。
结果CLOCK_MONOTONIC
不受NTP跳转的影响。但是由于相同的原因,它也不能用作绝对时间。 hrtime
仅对计算两次执行之间的时间有意义。
但是,假设hrtime
是单线程的,并且node
的定义总是递增的(例如here),随后对CLOCK_MONOTONIC
的调用应在增量方式,而不考虑吞吐量。
出于同样的原因,hrtime
是单线程的,以下简单函数可以解决相同的毫秒分辨率时间(如图所示):
node
在高吞吐量下,上述解决方案效果不佳。一秒只有1000毫秒,因此理论上每秒具有1000个或更多事件的吞吐量,很可能会将let myLastTime = 0;
function getMyTime() {
const newTime = new Date().getTime();
if (newTime > myLastTime) {
myLastTime = newTime;
return myLastTime;
}
if (newTime === myLastTime) {
myLastTime = newTime + 1;
returm myLastTime;
}
// bad case if NTP jump for instance
// and we need always increment time
if (newTime < myLastTime) {
myLastTime = myLastTime + 1;
return myLastTime;
}
}
时钟移到未来,从而导致更多的问题无法解决。但是对于使用单个编写器的1000个以下事件(即非分布式多主机方案)而言,吞吐量可能会有所帮助。
在分布式多主机环境中,无论如何,时间都不是命令的参考。由于每个主机的时钟的行为可能有所不同,因此也会产生NTP跳跃影响等。
结论,为了保证顺序的持久性,应用程序应该依赖保证其顺序的基础存储,或者应用程序应该通过逻辑序号或类似的数字来管理订单。