spring - 服务实例关闭时更新服务状态
问题描述
我使用 Spring Cloud Feign 客户端实现了请求。我试过这个:
假装客户端:
@FeignClient(name = "mail-service")
public interface EmailClient {
@RequestMapping(method = RequestMethod.POST, value = "/register")
void setUserRegistration(RegisterUserDTO registerUserDTO);
@RequestMapping(method = RequestMethod.POST, value = "/password_reset")
void setUserPasswordReset(PasswordResetDTO passwordResetDTO);
}
假装配置:
@Configuration
public class LoadBalancerConfiguration {
@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withBlockingDiscoveryClient()
.withSameInstancePreference()
.withHealthChecks()
.build(context);
}
}
请求 DTO:
@Getter
@Setter
public class PasswordResetDTO {
private int id;
}
控制器:
@Autowire
EmailClient emailClient;
@PostMapping("/dummy")
public ResponseEntity<?> test() {
RegisterUserDTO obj = new RegisterUserDTO();
obj.setId(12);
emailClient.setUserRegistration(obj);
return ok().build();
}
假装配置:
spring:
cloud:
loadbalancer:
ribbon:
enable: false
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: basic
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
instance:
preferIpAddress: true
POM.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
我启动了 3 个端点服务实例,它们以循环顺序从 Feign 客户端作为端点使用。到目前为止一切顺利,它按预期工作。但是,例如当我关闭第一个服务实例时,Feign 客户端不会收到此更改的通知,并继续向非活动服务发送请求。你知道当端点服务关闭并且不在活动服务列表中时如何通知消费者服务吗?我想我需要配置一些健康检查?
你知道我该如何解决这个问题吗?
测试问题的源代码:https ://github.com/rcbandit111/eureka-discovery-poc/tree/master
解决方案
功能区 - 负载均衡器
开箱即用,它为您提供循环负载平衡,但您可以实现自己的@RibbonClient
(甚至针对特定服务)并设计自定义负载平衡,例如基于 eureka 元数据。负载平衡发生在客户端。
Feign - Http 客户端
有了@FeignClient
您,您可以为您的其他服务(或基础架构之外的服务)快速开发客户端。它与功能区和尤里卡集成,因此您可以参考您的服务@FeignClient(yourServiceNameInEureka)
,最终得到的是一个客户端,它使用您的首选逻辑在注册实例之间进行负载平衡。如果您使用的是 spring,您可以使用熟悉的@RequestMapping
注解来描述您正在使用的端点。
我在下面提到了RandomRule
. 也可以在此处查看 Github以获取源代码。
@RibbonClient(name = "cloud-provider", configuration = CloudProviderConfiguration.class)
public class ConsumerApplication {
/* ... */
}
class CloudProviderConfiguration {
@Bean
public IRule ribbonRule(IClientConfig config) {
return new RandomRule();
}
}
另外,请参阅使用 Feign 设置高可用性负载均衡器
推荐阅读
- python - 查找二维数组中每一行唯一的元素
- python - Pandas 合并具有两列共同的表
- redis - 如何设置哨兵隧道
- json - 如何验证 json 键是否包含 Wiremock 中的特定值
- c++ - WiFi 工作时,您可以使用所有 ESP32 的 GPIO 引脚吗?
- c# - 在 CloudBlobDirectory 对象中按前缀列出 blob
- sql - django:通过从日期中提取月份和年份进行分组
- javascript - 我如何使用来自 div 类而不是数组的这些 JS 数组数据
- javascript - 我想在 ejs 中将字符串渲染为脚本
- exception - com.microsoft.sqlserver.jdbc.SQLServerException:列名“VALUE”无效