【问题标题】:Spring web application healthchecksSpring Web 应用程序健康检查
【发布时间】:2014-01-29 18:06:51
【问题描述】:

我正在 Amazon 的 Beanstalk 平台上部署基于 Spring 的 Web 应用程序,它们为我提供了为我的应用程序设置“健康检查”URL 路径的选项。

这个想法是,他们的平台将在部署后对该 URL 发出请求,以查看应用程序是否成功启动。因此,如果请求导致 HTTP 200,则应用程序可能没问题。但如果它导致 HTTP 500 或其他问题,则平台知道应用程序存在问题。

所以,我希望我可以开发某种 servlet 来检查 Spring 应用程序上下文是否已成功初始化,以向平台提供适当的 HTTP 响应代码。

有没有人尝试过这样的事情?出于类似目的?

我想知道 Spring 是否已经为此提供了一些优雅的解决方案。

【问题讨论】:

    标签: java spring amazon-web-services


    【解决方案1】:

    我建议使用Metrics 的健康检查功能。您可以设置许多扩展HealthCheck 类并实现check() 方法的类。这些健康检查实现将是 Spring 管理的 bean 本身,并且可以自动装配 Spring bean 并验证它们。然后配置HealthCheckServlet 监控应用状态。还要检查metrics-spring 项目。它将使 Spring 和 Metrics 的集成更简单。

    如果您使用 Java Spring 配置,您可能有一个像这样的 Metrics 配置,它从 metrics-spring 扩展 MetricsConfigurerAdapter

    @Configuration
    @EnableMetrics
    public class MetricsConfig extends MetricsConfigurerAdapter { }
    

    然后 @Import(value = {MetricsConfig.class}) 到你的 Spring 配置。

    您还需要并实现ServletContextListener 来连接HealthCheckServlet 和Spring。此HealthCheckContextListener 应添加到您的web.xml

    public class HealthCheckContextListener extends
        HealthCheckServlet.ContextListener implements ServletContextListener {
    
        private WebApplicationContext context;
    
        public HealthCheckContextListener(WebApplicationContext context) {
            this.context = context;
        }
    
        public HealthCheckContextListener() {}
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            this.context = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext()); 
            event.getServletContext().setAttribute(HealthCheckServlet.HEALTH_CHECK_REGISTRY,
                context.getBean(HealthCheckRegistry.class));
        }
    
        @Override
        protected HealthCheckRegistry getHealthCheckRegistry() {
            return (HealthCheckRegistry) context.getBean(HealthCheckRegistry.class);
        }
    }
    

    【讨论】:

    • 这个很有意思,但是WebApplicationContextUtils.getRequiredWebApplicationContext只有在Spring的ContextLoaderListener在web.xml中才有效,对吧?
    • 是的,ContextLoaderListener 应该在web.xml 中定义,或者如果您在没有web.xml 的Servlet 3.0 环境中运行,则应将其设置为实现WebApplicationInitializer Spring 接口的类中的侦听器跨度>
    • “..that extends HealthCheck class and implement ..”中的链接指的是 HealthCheckServlet 但应该是metrics.dropwizard.io/3.2.1/apidocs/com/codahale/metrics/health/…
    【解决方案2】:

    您可以做的最简单的事情是:

    @Controller
    class HealthCheckController {
    
        @ResponseStatus(OK)
        @RequestMapping(value = "/ping", method = HEAD) {
        public void ping() {
        }
    }
    

    可扩展以测试特定的 bean、DataSource 等。

    【讨论】:

    • 是的,但是这种方法的问题是,只有在应用程序上下文已正确初始化的情况下,控制器才会被激活,对吧?当然结果会是一些 HTTP 错误代码,但它不会来自我的代码。相反,它可能来自 Tomcat。
    • 没问题。如果应用程序上下文未初始化,那么您的应用程序无法运行,是吗?在这种情况下,Tomcat 将返回 404,这是完全合理的并且很容易被监视器捕获。如果应用上下文已初始化,但健康检查控制器发现有问题,您还可以返回 4XX 或 5XX 代码。如果一切正常,健康检查控制器将返回 200 或类似值。
    【解决方案3】:

    您应该考虑什么构成了对您来说健康的应用程序(例如,servlet 层?JMS 队列?FTP 服务器?等等),并让您的健康检查验证这些服务的可用性。显然,健康检查会频繁运行,因此您不想一遍又一遍地启动昂贵的操作。

    Spring Boot 是一个新项目,旨在通过支持约定而不是配置来简化 Spring 开发。他们实现了“健康检查”功能,您可以通过 Actuator add-in module 添加到项目中。

    这是对他们的健康检查implementation 的引用——它使用控制器类返回“ok”,如果有数据源,则尝试运行查询以确认数据库可访问(类似于“ SELECT .. from dual" 在 Oracle 语法中)。

    【讨论】:

    • 好点。对于我的具体情况,如果 Spring 的应用程序上下文已正确初始化,我喜欢认为我的应用程序处于健康状态。我的应用程序中可能发生的大多数错误都会导致 Spring bean 的创建和初始化失败。
    • 在 Spring Framework 中真正让我不安的一件事是,如果创建一个单一的 bean 失败,整个事情就会崩溃。我希望有办法实现更具弹性的应用程序上下文......
    【解决方案4】:

    这可以在 Spring Boot 框架中轻松完成。通过添加以下依赖项

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    您可以通过点击以下网址查看服务。

    localhost:serverPort/执行器/健康

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 2020-01-03
      相关资源
      最近更新 更多