Network Coordinates(网络坐标)
Consul使用网络层析成像系统来计算集群中节点的网络坐标。 这些坐标允许使用非常简单的计算在任意两个节点之间估计网络往返时间。 这允许许多有用的应用程序,例如查找最靠近请求节点的服务节点,或故障转移到下一个最近的数据中心中的服务。
所有这些都是通过使用Serf库提供的。 Serf的网络层析成像基于“Vivaldi:分散式网络坐标系统”,并基于其他研究进行了一些增强。 这里有关于Serf网络坐标的更多细节。
高级主题! 本页面涵盖了Consul内部的技术细节。 您无需了解这些详细信息即可有效运营和使用Consul。 这些详细信息记录在这里,供那些希望了解它们而无需深入了解源代码的用户。
Network Coordinates in Consul(Consul中的网络坐标)
网络坐标在Consul中以多种方式显示:
consul rtt命令可用于查询任意两个节点之间的网络往返时间。
Catalog endpoints和Health endpoints端点可以使用“?near =”参数根据给定节点的网络往返时间对查询结果进行排序。
Prepared queries可以根据网络往返时间自动将服务故障转移到其他Consul数据中心。 有关示例,请参阅Geo Failover。
Coordinate端点公开原始网络坐标以供在其他应用程序中使用。
Consul使用Serf来管理两个不同的gossip池,一个用于LAN,具有给定数据中心的成员,另一个用于WAN,其仅由所有数据中心中的Consul服务器组成。 请注意,这两个池之间的网络坐标不兼容,这一点很重要。 LAN坐标仅在使用其他LAN坐标进行计算时才有意义,而WAN坐标仅适用于其他WAN坐标。
Working with Coordinates(使用坐标)
一旦有了坐标,计算任意两个节点之间的估计网络往返时间就很简单了。 这是一个样本坐标,从Coordinate端点返回。
"Coord": {
"Adjustment": 0.1,
"Error": 1.5,
"Height": 0.02,
"Vec": [0.34,0.68,0.003,0.01,0.05,0.1,0.34,0.06]
}
除了不用于距离计算的误差项外,所有值都是以秒为单位的浮点数。
这是Go中的一个完整示例,展示了如何计算两个坐标之间的距离:
import (
"math"
"time"
"github.com/hashicorp/serf/coordinate"
)
func dist(a *coordinate.Coordinate, b *coordinate.Coordinate) time.Duration {
// Coordinates will always have the same dimensionality, so this is
// just a sanity check.
if len(a.Vec) != len(b.Vec) {
panic("dimensions aren't compatible")
}
// Calculate the Euclidean distance plus the heights.
sumsq := 0.0
for i := 0; i < len(a.Vec); i++ {
diff := a.Vec[i] - b.Vec[i]
sumsq += diff * diff
}
rtt := math.Sqrt(sumsq) + a.Height + b.Height
// Apply the adjustment components, guarding against negatives.
adjusted := rtt + a.Adjustment + b.Adjustment
if adjusted > 0.0 {
rtt = adjusted
}
// Go's times are natively nanoseconds, so we convert from seconds.
const secondsToNanoseconds = 1.0e9
return time.Duration(rtt * secondsToNanoseconds)
}