最近一直在做consul的压测,在开启acl的模式下,模拟consul client和springcloud consul中的接口进行发压,但是发现压力起来之后,服务的压力一直比较大。而且压力一直在一台机器(leader)上。查了一下consul的参数,发现有一种方式可以让三台机器都收到请求(读的情况下)。
1.1.2 一致性模式
绝大部分读请求Endpoint都支持多个级别的一致性,没有任何策略适合所有客户的需求,对于一致性模式的选择,用户通过权衡分布式系统的相关需求做出折中。
三种读模式:
•default - 如果没有指定,默认是强一致性。但是,有很小的可能性出现——新的Leader已经选出,但是旧的leader还在使用旧值。因此需要权衡快速读取和潜在的旧值风险。导致读取旧值的条件很难触发,大多数用户不需要担心此情况发生。此外,请注意,此竞争条件只适用于读取,而不是写入。
•consistent - 无附加条件的强一致性。要求Leader要与约定的个数的节点核实它仍然是领导者。引入额外的round-trip到所有服节点。因此,需要权衡round-trip带来的延迟增加返。大多数用户不应该使用该模式,除非不能容忍stale read。
•stale-这种模式允许任何服务器进行读操作,无论它是否是Leader。这意味着读取的值是有可能是旧值,但是,在leader的50ms内结果通常是一致的。需要权衡的是快速和可扩展的读取与更高可能性的久值。由于这种模式允许读操作没有Leader,因此即使集群是无效的,仍然可以响应读操作。
具体配置是增加一个AllowStale即可。
func catalog(client *api.Client) {
idx = 1
catalog := client.Catalog()
services, _, err := catalog.Services(&api.QueryOptions{
WaitTime: 2 * time.Second,
Token: token,
WaitIndex: idx,
AllowStale: true,
})
if err != nil {
fmt.Printf("catalog error occurred: %v\n", err)
} else {
fmt.Printf("total services: %d\n", len(services))
}
}