java - Spring Cloud Consul 客户端不会忽略关键服务
问题描述
我已经实现了一个基于 Spring Cloud 的应用程序,它具有以下主要架构。多个实例的GatewayService
委托HelloService
。我使用Consul进行服务发现。GatewayService
是通过以下方式实现的:
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
@RestController
static class GateWayController {
private final WebClient.Builder webClientBuilder;
@Data
@NoArgsConstructor
private static class Response {
private String message;
private String appName;
private int port;
}
@Autowired
public GateWayController(WebClient.Builder webClientBuilder) {
this.webClientBuilder = webClientBuilder;
}
@GetMapping("/lbhello")
public Mono<Response> hello() {
return webClientBuilder.build()
.get()
.uri("lb://hello-service/hello")
.retrieve()
.bodyToMono(Response.class);
}
}
}
spring-cloud-starter-consul-discovery
并spring-cloud-starter-loadbalancer
作为依赖项包含在pom.xml
. 在application.yaml
我只设置application.name
和禁用Ribbon,以便使用Spring Cloud Loadbalancer。当我启动GatewayService
和两个实例时,HelloService
一切都按预期工作。对端点的服务调用lbhello
交替委托给两个HelloService
实例。
当一个实例HelloService
停止时,Consul检测到该实例缺少一个将其标记为关键的实例。因此,我希望负载均衡器至少在一段时间后停止将请求转发到不存在的服务。但这永远不会发生。每隔一个服务调用就会委托给这个服务实例,因此会失败。当使用Eureka作为发现服务时,注册表会被调整,只有剩余HelloService
的被考虑用于服务调用。
这是Consul的预期行为吗?如果答案是肯定的,是否有 Spring Cloud 设置来适应这种行为?
解决方案
Spring CloudConsulDiscoveryClient
默认加载所有服务实例,无论它们的健康状态如何。可以通过以下配置设置更改此行为:
spring.cloud.consul.discovery.query-passing = true
使用此设置,请求不会在延迟一段时间后委托给非健康实例。
推荐阅读
- mongodb - 计算不同值并将其作为对象返回的最有效方法
- angular - Ionic Cordova ios 在滚动时闪烁
- c++ - 有没有办法在 OpenCV 中本地解决二次规划问题?
- django - 在 django 启动期间设置全局设置
- php - WordPress 插件开发:如何将文件上传到默认的“上传”目录?
- google-sheets - 如何在 Google 表格的过滤器中使用 REGEXMATCH 和 SPLIT?
- java - 如何在 java 中调整动画 gif 文件的大小?
- c# - 在 C# 中打开 Excel 文件并调用加载项命令
- csv - 为什么这段代码不将给定的数字分成 .csv 文件中的不同列?
- amazon-web-services - AWS CloudFront 和 ELB:请求未到达后端