开发者社区 > 云原生 > 正文

在服务重启时,如何处理服务还没启动完成 nacos就已注册成功问题?

springCloud集成nacos,在服务重启时,如何处理服务还没启动完成 nacos就已注册成功问题?

展开
收起
三分钟热度的鱼 2023-05-23 15:13:25 298 0
2 条回答
写回答
取消 提交回答
  • 在Spring Cloud中,可以使用@EnableAutoConfiguration@ConfigurationProperties注解来配置和使用Nacos。在服务重启时,如果服务还没有启动完成,可以通过以下方式来处理:

    1. 使用@EnableAutoConfiguration@ConfigurationProperties注解配置Nacos,并在服务启动时使用@EnableAutoConfiguration@ConfigurationProperties注解来配置其他相关配置。例如:

      @Configuration
      @EnableAutoConfiguration
      public class AppConfig implements ConfigApplicationContextAware {
         private ConfigApplicationContext applicationContext;
      
         @Override
         public void setConfigApplicationContext(ConfigApplicationContext applicationContext) {
             this.applicationContext = applicationContext;
         }
      }
      
      @ConfigurationProperties(prefix = "nacos")
      public class Config {
         private String appName;
         private String appService;
      }
      

      在上面的代码中,我们使用@ConfigurationProperties注解来配置Config类,并将appNameappService属性指定为服务的名称和名称。

    2. 在服务启动时,使用@EnableAutoConfiguration@ConfigurationProperties注解来配置其他相关配置,例如DNS服务器等。例如:

      @SpringBootApplication
      @EnableAutoConfiguration
      public class MyApplication {
         public static void main(String[] args) {
             SpringApplication.run(MyApplication.class, args);
         }
      }
      

      在上面的代码中,我们使用@SpringBootApplication注解来启动应用程序,并使用@EnableAutoConfiguration注解来启用自动配置。

      在服务启动时,我们可以使用@ConfigurationProperties注解来配置其他相关配置,例如DNS服务器等。例如:

      @ConfigurationProperties(prefix = "nacos")
      public class DNSConfig {
         private String domain;
         private String server;
      }
      

      在上面的代码中,我们使用@ConfigurationProperties注解来配置DNSConfig类,并将domainserver属性指定为DNS服务器的名称和名称。

    通过以上两种方式,我们可以在服务重启时,处理服务还没启动完成的问题。不过没必要耦合一个mq spring boot 2.3以上配置好优雅停机 就支持了。此回答整理自钉群“Nacos社区群3”

    2023-05-23 16:53:50
    赞同 展开评论 打赏
  • 随心分享,欢迎友善交流讨论:)

    在 Spring Cloud 集成 Nacos 时,可能会出现服务还没启动完成 Nacos 就已经注册成功的问题,这会导致服务在 Nacos 上显示为健康的状态,但实际上服务还未完全启动完成,会导致服务调用失败。

    为了解决这个问题,可以在服务启动时增加一个健康检查接口,当服务启动完成后,该接口返回健康状态,同时通知 Nacos 更新服务的健康状态。在 Nacos 注册服务时,设置服务的健康检查地址为该接口地址,并设置服务的健康检查间隔时间。

    示例代码:

    在服务中增加一个健康检查接口: @RestController public class HealthController {

    private volatile boolean isHealth = false;
    
    @GetMapping("/health")
    public String health() {
        if (isHealth) {
            return "UP";
        } else {
            return "DOWN";
        }
    }
    
    public void setHealth(boolean health) {
        isHealth = health;
    }
    

    } 在服务启动完成后,将健康状态设置为 true,并通知 Nacos 更新服务的健康状态: @Service public class MyService implements ApplicationRunner {

    @Autowired
    private HealthController healthController;
    
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 启动服务
        // ...
    
        // 设置健康状态为 true,并通知 Nacos 更新服务的健康状态
        healthController.setHealth(true);
        NamingService namingService = NamingFactory.createNamingService("127.0.0.1:8848");
        Instance instance = new Instance();
        instance.setIp("127.0.0.1");
        instance.setPort(8080);
        instance.setHealthy(true);
        instance.setMetadata(new HashMap<String, String>() {{
            put("version", "1.0");
        }});
        namingService.registerInstance("my-service", instance);
    }
    

    } 在 Nacos 注册服务时,设置服务的健康检查地址为健康检查接口的地址,并设置健康检查间隔时间: spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 health-check: enabled: true interval: 5s path: /health type: http 这样,只有当服务启动完成后,健康检查接口返回 UP 状态时,Nacos 才会将服务标记为健康状态,避免了服务还未启动完成就已经注册成功的问题。

    2023-05-23 16:45:31
    赞同 展开评论 打赏

阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。

相关电子书

更多
Nacos架构&原理 立即下载
workshop专场-微服务专场-开发者动手实践营-微服务-使用Nacos进行服务的动态发现和流量调度 立即下载
Nacos 启航,发布第一个版本, 云原生时代助力用户微服务平台建设 立即下载