首页 > 解决方案 > 服务实例关闭时更新服务状态

问题描述

我使用 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

标签: springspring-bootspring-cloudspring-cloud-feignspring-cloud-loadbalancer

解决方案


功能区 - 负载均衡器

开箱即用,它为您提供循环负载平衡,但您可以实现自己的@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 设置高可用性负载均衡器


推荐阅读