任何一个服务若是没有监控,那就是两眼一抹黑,没法知道当前服务的运行状况,也就没法对可能出现的异常情况进行很好的处理,因此对任意一个服务来讲,监控都是必不可少的。java
就目前而言,大部分微服务应用都是基于 SpringBoot
来构建,因此了解 SpringBoot
的监控特性是很是有必要的,而 SpringBoot
也提供了一些特性来帮助咱们监控应用。web
本文基于 SpringBoot 2.3.1.RELEASE
版本演示。spring
SpringBoot
中的监控能够分为 HTTP
端点和 JMX
两种方式来监控当前应用的运行情况和指标收集json
执行器端点容许您监视应用程序并与之交互。SpringBoot
包括许多内置的端点,并容许咱们添加本身的端点。能够经过 HTTP
或 JMX
启用或禁用每一个端点,并公开(使其能够远程访问)。每一个端点都有一个惟一的 id
,访问时能够经过以下地址进行访问:http:ip:port/{id}
(SpringBoot 1.x ),而在 SpringBoot 2.x
版本中,默认新增了一个 /actuator
做为基本路,访问地址则对应为 :http:ip:port/actuator/{id}
。缓存
使用 HTTP
监控很是简单,在 SpringBoot
项目中,引入以下依赖:tomcat
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
默认就能够经过地址 http:localhost:8080/actuator/health
,访问以后获得以下结果:安全
SpringBoot
中提供了很是多的默认端点监控,可是出于安全考虑,默认状况下有些端点并非开启状态,如 shutdown
端点就是默认关闭的。springboot
SpringBoot
中默认提供的经常使用内置端点以下:服务器
端点 id | 描述 |
---|---|
auditevents | 公开当前应用程序的审计事件信息,须要 AuditEventRepository Bean。 |
beans | 展现程序中全部的 Bean。 |
caches | 公开可用的缓存。 |
conditions | 展现配置类或者自动装配类中的条件,以及它们匹配或者不匹配的缘由。 |
configprops | 显示全部 @ConfigurationProperties 中的配置属性。 |
env | 显示 ConfigurableEnvironment 中的全部环境。 |
health | 显示应用程序运行情况信息。 |
httptrace | 显示 HTTP 跟踪信息(默认状况下统计最近 100 次请求),须要 HttpTraceRepository Bean。 |
info | 显示任意程序信息。 |
integrationgraph | 显示 Spring 集成图,须要依赖 spring-integration-core。 |
loggers | 展现和修改应用中的 loggers 配置。 |
metrics | 展现当前应用监控指标的度量。 |
mappings | 展现全部 @RequestMapping 路径。 |
scheduledtasks | 展现应用中的全部定时任务信息。 |
sessions | 容许从 Spring 会话支持的会话存储中检索和删除用户会话。须要使用基于 Spring Session web应用程序。 |
shutdown | 优雅的关闭程序,默认禁止了该端点的访问。 |
虽说这里的大部分端点都是默认开启的,可是默认暴露(容许对外访问)的只有 health
和 info
端点,因此若是须要容许端点对外暴露,能够经过以下配置(若是想要暴露全部的端点,则能够直接配置 "*"
):session
management: endpoints: web: exposure: include: [health,info,mappings] //或者直接配置 "*"
另外,开启或禁用某一个端点,也能够经过经过以下配置进行动态控制:
management.endpoint.<id>.enabled=true
接下来咱们挑选几个重点的端点来介绍一下。
health
断点默认只是展现当前应用健康信息,可是咱们能够经过另外一个配置打开详细信息,这样不只仅会监控当前应用,还会监控与当前应用相关的其余第三方应用,如 Redis
。
management: endpoint: health: show-details: always
这个配置打开以后,咱们链接上 Redis
以后再次访问 health
端点,就能够展现 Redis
服务的健康信息了:
访问 http://localhost:8080/actuator/loggers
能够查看当前应用的日志级别等信息:
这里面自己并不特别,可是有一个功能却很是有用,好比咱们生产环境日志级别通常都是 info
,可是如今有一个 bug
经过 info
级别没法排查,那么咱们就能够临时修改 log
级别。
好比上图中的 ROOT
节点是 info
级别,那么咱们能够经过 postman
等工具来发一个 post
请求修改日志级别。
修改以后就会发现,日志由原来的 info
变成了 debug
:
metrics
是一个很是重要的监控端点,其监控内容覆盖了 JVM
内存、堆、类加载、处理器和 tomcat
容器等一些重要指标:
能够看到这里面包含了很是多的指标,任意访问一个指标就能够查看对应的指标信息:
经过上面的介绍,能够看到 SpringBoot
提供的监控很是强大,可是就算再全面的监控也不可能知足全部人的需求,因此 SpringBoot
也支持自定义监控端点。
自定义一个监控端点主要有以下经常使用注解:
HTTP
和 JMX
两种方式。HTTP
方式。JMX
方式。以上三个注解做用在类上,表示当前类是一个监控端点,另外还有一些注解会用在方法和参数上:
Get
方法请求)。Post
方法请求)。Delete
方法请求)。@Endpoint
注解标注标识,同时定义几个方法用 @ReadOperation
和 @WriteOperation
注解来标注:@Endpoint(id="myEndpoint") @Component public class MyEndpoint { private String STATUS = "up"; private String DETAIL = "一切正常"; // @ReadOperation // public String test1(){ // return "wolf"; // } // @ReadOperation // public Map<String,String> test2(){ // Map<String,String> map = new HashMap(); // map.put("status","up"); // return map; // } @ReadOperation public JSONObject test3(){ JSONObject jsonObject= new JSONObject(); jsonObject.put("status",STATUS); jsonObject.put("detail",DETAIL); return jsonObject; } @ReadOperation public JSONObject test3_1(@Selector String name){ JSONObject jsonObject= new JSONObject(); if ("status".equals(name)){ jsonObject.put("status",STATUS); }else if ("detail".equals(name)){ jsonObject.put("detail",DETAIL); } return jsonObject; } @WriteOperation//动态修改指标 public void test4(@Selector String name,@Nullable String value){ if (!StringUtils.isEmpty(value)){ if ("status".equals(name)){ STATUS = value; }else if ("detail".equals(name)){ DETAIL = value; } } } }
@Component
注解表示将该类交给 Spring
进行管理,或者也能够再定义一个 Configuration
类来加载该 Bean
也能够,固然,若是咱们须要提供给第三方使用,若是没法保证当前包名被扫描,则须要使用 SpringBoot
的自动装配机制将该类进行管理。@ReadOperation
方法能够返回 String
或者 JSONObject
或者 Map
集合等。@Selector
注解则表示访问断端点的时候能够直接访问子节点。完成了上面的类,启动 SpringBoot
应用,接下来就能够直接经过 http://localhost:8080/actuator/myEndpoint
进行访问了:
同时,由于 test3_1
方法使用了 @Selector
注解,因此咱们能够经过这个方法每个指标的明细:
而带有 @WriteOperation
注解的方法能够用来修改指标,这个方法须要用 post
进行访问,访问的参数能够直接使用字符串传参,也能够直接使用 json
进行传参,修改以后再次查看就能够发现指标已经被动态修改:
JMX
全称为 Java Management Extensions,即 Java
管理扩展。它提供了对 Java
应用程序和 JVM
的监控管理。经过JMX
咱们能够监控服务器中各类资源的使用状况以及线程,内存和 CPU
等使用状况。
打开 jdk
下提供的工具 jConsole
:
打开以后这里会监控到咱们已经启动的应用,双击进入:
SystemInfoMBean
(注意名字必需要用 MBean
结尾):public interface SystemInfoMBean { int getCpuCore(); long getTotalMemory(); void shutdown(); }
SystemInfoMBean
接口,实现类的明明方式为接口名去掉 MBean
:public class SystemInfo implements SystemInfoMBean { @Override public int getCpuCore() { return Runtime.getRuntime().availableProcessors(); } @Override public long getTotalMemory() { return Runtime.getRuntime().totalMemory(); } @Override public void shutdown() { System.exit(0); } }
public class JmxRegisterMain { public static void main(String[] args) throws NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, MalformedObjectNameException, IOException { MBeanServer mBeanServer= ManagementFactory.getPlatformMBeanServer(); ObjectName objectName=new ObjectName("com.lonely.wolf.note.springboot.actuator.jmx:type=SystemInfo"); SystemInfo SystemInfo =new SystemInfo(); mBeanServer.registerMBean(SystemInfo,objectName);//注册 System.in.read();//防止程序结束 } }
运行该 main
方法,再打开 jConsole
就能够看到成功注册了一个 MBean
:
一样的,Spring
当中只要咱们使用了 @@Endpoint
或者 @JmxEndpoint
注解,就会自动帮咱们注册一个 MBean
,其原理也是利用了自动装配机制。
除了 SpringBoot
自带的监控以外,也有其余第三方开源的强大监控系统,如 Prometheus
,并且 SpringBoot
也将其进行了集成,使用 Prometheus
时只须要引入以下 jar
包便可:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
固然,若是使用 Prometheus
的话须要单独安装,并且通常会选择 Prometheus
+ Grafana
来共同实现一个监控平台,在这里就不作过多介绍,若是感兴趣的朋友能够本身去了解下这两种软件的使用。
本文主要讲述了 Spring Boot actuator
的使用,并分别介绍了其中两种监控类型 HTTP
和 JMX
,最后经过一个例子来实现了自定义的端点,同时也实现了手动注册一个 MBean
的方法。