前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官:SpringBoot 服务监控怎么做?线程,JVM堆信息怎么收集?

面试官:SpringBoot 服务监控怎么做?线程,JVM堆信息怎么收集?

作者头像
架构师修炼
发布2021-09-10 15:08:55
8240
发布2021-09-10 15:08:55
举报

今年面试了非常多的程序员,不少人简历中写着会 SpringCloud、SpringBoot。于是我问,你们的服务监控是用什么做的?不少人就当场露馅了,我自己都感觉很不好意思继续追问,感觉圆场。

这里我摘录几个回答,大家看看:监控功能还没做;监控功能是其他人写的,我不太清楚;监控是运维的工作,运维团队维护的,具体我不清楚。。。

这就是很多人做微服务,或者学微服务,以及进行微服务的架构转型所忽略的,服务监控这块没有跟上。

刚好这两天群里也有人在讨论这个问题,因此今天我们一起来讨论一下,微服务的监控如何做?由于大部分企业的微服务应用都是 SpringBoot 应用,因此我这里自然而然的想到了借助 Spring Boot 的 Actuator 模块。(没吃过猪肉总听过猪叫见过猪跑吧🤪)。

这篇文章是我在完成公司架构变更之后,对 SpringBoot Actuator 模块学习应用的总结。在本篇文章中,你可以学习到:

「1、」 Spring Boot Actuator 的快速使用入门 「2、」 Spring Boot Actuator 的一些重要的 endpoints 的介绍 「3、」 如何通过 Actuator 模块实时查看当前应用的线程 dump 信息 「4、」 如何通过 Actuator 模块实时查看当前应用的堆信息 「5、」 如何通过 Actuator 模块实时修改当前应用的日志打印等级 「6、」 ...

后面找机会我还会介绍:

TODO:SpringBoot 微服务应用集成 Prometheus + Grafana 实现监控告警

什么是 Spring Boot Actuator

Spring Boot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监控和管理 Spring Boot 应用。这个模块是一个采集应用内部信息暴露给外部的模块,上述的功能都可以通过HTTP 和 JMX 访问。

因为暴露内部信息的特性,Actuator 也可以和一些外部的应用监控系统整合(Prometheus, Graphite,DataDog,Influx,Wavefront,New Relic等)。这些监控系统提供了出色的仪表板,图形,分析和警报,可帮助你通过一个统一友好的界面,监视和管理你的应用程序。

Actuator 使用 Micrometer 与这些外部应用程序监视系统集成。这样一来,只需很少的配置即可轻松集成外部的监控系统。

❝Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只需要使用 Micrometer 的通用 API 来收集性能指标即可。Micrometer 会负责完成与不同监控系统的适配工作。这就使得切换监控系统变得很容易。 对比 Slf4j 之于 Java Logger 中的定位。 ❞

快速开始,创建一个Spring Boot Actuator Demo

我们先创建一个 demo 应用。

「你可以通过 Spring Boot CLI 创建:」

spring init -d=web,actuator -n=actuator-demo actuator-demo

「或者通过 Spring Initializr 创建:」

Spring Initializr

「对应的 maven 依赖:」

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

「对应的 Gradle 依赖:」

dependencies {  
    compile("org.springframework.boot:spring-boot-starter-actuator")  
}

Endpoints 介绍

Spring Boot 提供了所谓的 endpoints (下文翻译为端点)给外部来与应用程序进行访问和交互。

打比方来说,/health 端点 提供了关于应用健康情况的一些基础信息。metrics 端点提供了一些有用的应用程序指标(JVM 内存使用、系统 CPU 使用等)。

这些 Actuator 模块本来就有的端点我们称之为原生端点。根据端点的作用的话,我们大概可以分为三大类:

应用配置类: 获取应用程序中加载的应用配置、环境变量、自动化配置报告等与 Spring Boot 应用密切相关的配置类信息。

度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP 请求统计等。

操作控制类:提供了对应用的关闭等操作类功能。

❝详细的原生端点介绍,请以官网为准,这里就不赘述徒增篇幅。 ❞

需要注意的就是:

1、每一个端点都可以通过配置来单独禁用或者启动

2、不同于 Actuator 1.x,「Actuator 2.x 的大多数端点默认被禁掉」。Actuator 2.x 中的默认端点增加了/actuator前缀。默认暴露的两个端点为/actuator/health/actuator/info

端点暴露配置

我们可以通过以下配置,来配置通过 JMX 和 HTTP 暴露的端点。

端点暴露配置

可以打开所有的监控点。

management.endpoints.web.exposure.include=\*

也可以选择打开部分,"*" 代表暴露所有的端点,如果指定多个端点,用","分开。

management.endpoints.web.exposure.exclude=beans,trace

Actuator 默认所有的监控点路径都在/actuator/*,当然如果有需要这个路径也支持定制。

management.endpoints.web.base-path=/minitor

设置完重启后,再次访问地址就会变成/minitor/*

「现在我们按照如下配置:」

# "\*" 代表暴露所有的端点 如果指定多个端点,用","分开  
management.endpoints.web.exposure.include=\*  
# 赋值规则同上  
management.endpoints.web.exposure.exclude=

启动 demo 程序,访问http://localhost:8080/actuator,查看暴露出来的端点:

actuator监控

❝上面这样显示是因为 chrome 浏览器安装了 JSON-handle 插件,实际上就是返回一大段 json。 ❞

下面,我会着重介绍几个比较重要的端点。

重要端点解析

/health端点

/health端点会聚合你程序的健康指标,来检查程序的健康情况。端点公开的应用健康信息取决于:

management.endpoint.health.show-details=always

该属性可以使用以下值之一进行配置:

端点解析

按照上述配置,配置成always之后,我们启动项目,访问http://localhost:8080/actuator/health端口,可以看到这样的信息:

health端口

是不是感觉好像健康信息有点少?先别急,那是因为我们创建的是一个最基础的 Demo 项目,没有依赖很多的组件。

/health端点有很多自动配置的健康指示器:如 redis、rabbitmq、db 等组件。当你的项目有依赖对应组件的时候,这些健康指示器就会被自动装配,继而采集对应的信息。如上面的 diskSpace 节点信息就是DiskSpaceHealthIndicator在起作用。

DiskSpaceHealthIndicator

❝上述截图取自官方文档 ❞

这是我另一个项目的/health端点信息。

/health端点信息

当如上的组件有一个状态异常,应用服务的整体状态即为 down。我们也可以通过配置禁用某个组件的健康监测。

management.health.mongo.enabled: false

「或者禁用所有自动配置的健康指示器:」

management.health.defaults.enabled: false

自定义 Health Indicator

当然你也可以自定义一个Health Indicator,只需要实现HealthIndicator 接口或者继承AbstractHealthIndicator类。

@Component  
public class CustomHealthIndicator extends AbstractHealthIndicator {
    @Override  
    protected void doHealthCheck(Health.Builder builder) throws Exception {  
        // 使用 builder 来创建健康状态信息  
        // 如果你throw 了一个 exception,那么status 就会被置为DOWN,异常信息会被记录下来  
        builder.up()  
                .withDetail("app", "这个项目很健康")  
                .withDetail("error", "Nothing, I'm very good");  
    }  
}

「最终效果:」

自定义 Health Indicator

5.2 /metrics端点

/metrics端点用来返回当前应用的各类重要度量指标,比如:内存信息、线程信息、垃圾回收信息、tomcat、数据库连接池等。

{  
    "names": [  
        "tomcat.threads.busy",  
        "jvm.threads.states",  
        "jdbc.connections.active",  
        "jvm.gc.memory.promoted",  
        "http.server.requests",  
        "hikaricp.connections.max",  
        "hikaricp.connections.min",  
        "jvm.memory.used",  
        "jvm.gc.max.data.size",  
        "jdbc.connections.max",  
         ....  
    ]  
}

不同于 1.x,Actuator 在这个界面看不到具体的指标信息,只是展示了一个指标列表。为了获取到某个指标的详细信息,我们可以请求具体的指标信息,像这样:

http://localhost:8080/actuator/metrics/{MetricName}

比如我访问/actuator/metrics/jvm.memory.max,返回信息如下:

jvm.memory.max

你也可以用 query param 的方式查看单独的一块区域。比如你可以访问/actuator/metrics/jvm.memory.max?tag=id:Metaspace。结果就是:

Metaspace

/loggers端点

/loggers 端点暴露了我们程序内部配置的所有 logger 的信息。我们访问/actuator/loggers可以看到

loggers端点

你也可以通过下述方式访问单独一个 logger。

http://localhost:8080/actuator/loggers/{name}

比如我现在访问 root logger,http://localhost:8080/actuator/loggers/root

{  
    "configuredLevel": "INFO",  
    "effectiveLevel": "INFO"  
}

改变运行时的日志等级

/loggers端点我最想提的就是这个功能,能够动态修改你的日志等级。

比如,我们可以通过下述方式来修改 root,logger 的日志等级。我们只需要发起一个 URL 为http://localhost:8080/actuator/loggers/rootPOST请求,POST 报文如下:

{  
   "configuredLevel": "DEBUG"  
}

POST请求

仔细想想,这个功能是不是非常有用。「如果在生产环境中,你想要你的应用输出一些 Debug 信息以便于你诊断一些异常情况,你你只需要按照上述方式就可以修改,而不需要重启应用。」

❝如果想重置成默认值,把 value 改成 null

/info端点

/info端点可以用来展示你程序的信息。我理解过来就是一些程序的基础信息。并且你可以按照自己的需求在配置文件application.properties中个性化配置(默认情况下,该端点只会返回一个空的 json 内容。):

info.app.name=actuator-test-demo  
info.app.encoding=UTF-8  
info.app.java.source=1.8  
info.app.java.target=1.8  
# 在 maven 项目中你可以直接用下列方式引用 maven properties的值  
# info.app.encoding=@project.build.sourceEncoding@  
# info.app.java.source=@java.version@  
# info.app.java.target=@java.version@

启动项目,访问http://localhost:8080/actuator/info

{  
    "app": {  
        "encoding": "UTF-8",  
        "java": {  
            "source": "1.8.0_131",  
            "target": "1.8.0_131"  
        },  
        "name": "actuator-test-demo"  
    }  
}

/beans端点

/beans端点会返回 Spring 容器中所有 bean 的别名、类型、是否单例、依赖等信息。

访问http://localhost:8080/actuator/beans,返回如下:

beans端点

/heapdump 端点

访问:http://localhost:8080/actuator/heapdump会自动生成一个 Jvm 的堆文件 heapdump。我们可以使用 JDK 自带的 Jvm 监控工具 VisualVM 打开此文件查看内存快照。

VisualVM查看内存快照

/threaddump 端点

这个端点我个人觉得特别有用,方便我们在日常定位问题的时候查看线程的情况。主要展示了线程名、线程 ID、线程的状态、是否等待锁资源、线程堆栈等信息。就是可能查看起来不太直观。访问http://localhost:8080/actuator/threaddump返回如下:

threaddump 端点

/shutdown端点

这个端点属于操作控制类端点,可以优雅关闭 Spring Boot 应用。要使用这个功能首先需要在配置文件中开启:

management.endpoint.shutdown.enabled=true

由于 「shutdown 接口默认只支持 POST 请求」,我们启动Demo项目,向http://localhost:8080/actuator/shutdown发起POST请求。返回信息:

{  
    "message": "Shutting down, bye..."  
}

然后应用程序被关闭。

由于开放关闭应用的操作本身是一件「非常危险」的事,所以真正在线上使用的时候,我们需要对其加入一定的保护机制,比如:「定制 Actuator 的端点路径、整合 Spring Security 进行安全校验」等。(不是特别必要的话,这个端点不用开)

整合 Spring Security 对端点进行安全校验

由于端点的信息和产生的交互都是非常敏感的,必须防止未经授权的外部访问。如果您的应用程序中存在「Spring Security」的依赖,则默认情况下使用「基于表单的 HTTP 身份验证」来保护端点。

如果没有,只需要增加对应的依赖即可:

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

添加之后,我们需要定义安全校验规则,来覆盖 Spring Security 的默认配置。

这里我给出了两个版本的模板配置:

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;  
import org.springframework.boot.actuate.context.ShutdownEndpoint;  
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration  
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {

    /\*  
     \* version1:  
     \* 1. 限制 '/shutdown'端点的访问,只允许ACTUATOR\_ADMIN访问  
     \* 2. 允许外部访问其他的端点  
     \* 3. 允许外部访问静态资源  
     \* 4. 允许外部访问 '/'  
     \* 5. 其他的访问需要被校验  
     \* version2:  
     \* 1. 限制所有端点的访问,只允许ACTUATOR\_ADMIN访问  
     \* 2. 允许外部访问静态资源  
     \* 3. 允许外部访问 '/'  
     \* 4. 其他的访问需要被校验  
     \*/

    @Override  
    protected void configure(HttpSecurity http) throws Exception {  
        // version1  
//        http  
//                .authorizeRequests()  
//                    .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))  
//                        .hasRole("ACTUATOR\_ADMIN")  
//                .requestMatchers(EndpointRequest.toAnyEndpoint())  
//                    .permitAll()  
//                .requestMatchers(PathRequest.toStaticResources().atCommonLocations())  
//                    .permitAll()  
//                .antMatchers("/")  
//                    .permitAll()  
//                .antMatchers("/\*\*")  
//                    .authenticated()  
//                .and()  
//                .httpBasic();

        // version2  
        http  
                .authorizeRequests()  
                .requestMatchers(EndpointRequest.toAnyEndpoint())  
                    .hasRole("ACTUATOR\_ADMIN")  
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations())  
                    .permitAll()  
                .antMatchers("/")  
                    .permitAll()  
                .antMatchers("/\*\*")  
                    .authenticated()  
                .and()  
                .httpBasic();  
    }  
}

application.properties的相关配置如下:

# Spring Security Default user name and password  
spring.security.user.name=actuator  
spring.security.user.password=actuator  
spring.security.user.roles=ACTUATOR_ADMIN
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 架构师修炼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 Spring Boot Actuator
  • 快速开始,创建一个Spring Boot Actuator Demo
  • Endpoints 介绍
  • 端点暴露配置
  • 重要端点解析
    • /health端点
      • 自定义 Health Indicator
        • 5.2 /metrics端点
          • /loggers端点
            • 改变运行时的日志等级
              • /info端点
                • /beans端点
                  • /heapdump 端点
                    • /threaddump 端点
                      • /shutdown端点
                      • 整合 Spring Security 对端点进行安全校验
                      相关产品与服务
                      Prometheus 监控服务
                      Prometheus 监控服务(TencentCloud Managed Service for Prometheus,TMP)是基于开源 Prometheus 构建的高可用、全托管的服务,与腾讯云容器服务(TKE)高度集成,兼容开源生态丰富多样的应用组件,结合腾讯云可观测平台-告警管理和 Prometheus Alertmanager 能力,为您提供免搭建的高效运维能力,减少开发及运维成本。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档