springboot 使用Spring Boot Actuator监控应用小结
微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的处理和传递,出现了异常如何快速定位是哪个环节出现了问题? 在这种框架下,微服务的监控显得尤为重要。本文主要结合Spring Boot Actuator,跟大家一起分享微服务Spring Boot Actuator的常见用法,方便我们在日常中对我们的微服务进行监控治理。 Actuator监控 Spring Boot使用“习惯优于配置的理念”,采用包扫描和自动化配置的机制来加载依赖jar中的Spring bean,不需要任何Xml配置,就可以实现Spring的所有配置。虽然这样做能让我们的代码变得非常简洁,但是整个应用的实例创建和依赖关系等信息都被离散到了各个配置类的注解上,这使得我们分析整个应用中资源和实例的各种关系变得非常的困难。 Actuator是Spring Boot提供的对应用系统的自省和监控的集成功能,可以查看应用配置的详细信息,例如自动化配置信息、创建的Spring beans以及一些环境属性等。 Actuator监控只需要添加以下依赖就可以完成 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> 为了保证actuator暴露的监控接口的安全性,需要添加安全控制的依赖spring-boot-start-security依赖,访问应用监控端点时,都需要输入验证信息。Security依赖,可以选择不加,不进行安全管理,但不建议这么做。 Actuator 的 REST 接口 Actuator监控分成两类:原生端点和用户自定义端点;自定义端点主要是指扩展性,用户可以根据自己的实际应用,定义一些比较关心的指标,在运行期进行监控。 原生端点是在应用程序里提供众多 Web 接口,通过它们了解应用程序运行时的内部状况。原生端点又可以分成三类:
Actuator 提供了 13 个接口,具体如下表所示。
快速上手 相关配置 项目依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> 配置文件 server: port: 8080 management: security: enabled: false #关掉安全认证 port: 8088 #管理端口调整成8088 context-path: /monitor #actuator的访问路径 endpoints: shutdown: enabled: true info: app: name: spring-boot-actuator version: 1.0.0
配置完成之后,启动项目就可以继续验证各个监控功能了。 命令详解 autoconfig Spring Boot的自动配置功能非常便利,但有时候也意味着出问题比较难找出具体的原因。使用 autoconfig 可以在应用运行时查看代码了某个配置在什么条件下生效,或者某个自动配置为什么没有生效。 启动示例项目,访问: http://localhost:8088/monitor/autoconfig 返回部分信息如下: { "positiveMatches": { "DevToolsDataSourceAutoConfiguration": { "notMatched": [ { "condition": "DevToolsDataSourceAutoConfiguration.DevToolsDataSourceCondition","message": "DevTools DataSource Condition did not find a single DataSource bean" } ],"matched": [ ] },"RemoteDevToolsAutoConfiguration": { "notMatched": [ { "condition": "OnPropertyCondition","message": "@ConditionalOnProperty (spring.devtools.remote.secret) did not find property 'secret'" } ],"matched": [ { "condition": "OnClassCondition","message": "@ConditionalOnClass found required classes 'javax.servlet.Filter','org.springframework.http.server.ServerHttpRequest'; @ConditionalOnMissingClass did not find unwanted class" } ] } } } configprops 查看配置文件中设置的属性内容,以及一些配置属性的默认值。 启动示例项目,访问: http://localhost:8088/monitor/configprops 返回部分信息如下: { ... "environmentEndpoint": { "prefix": "endpoints.env","properties": { "id": "env","sensitive": true,"enabled": true } },"spring.http.multipart-org.springframework.boot.autoconfigure.web.MultipartProperties": { "prefix": "spring.http.multipart","properties": { "maxRequestSize": "10MB","fileSizeThreshold": "0","location": null,"maxFileSize": "1MB","enabled": true,"resolveLazily": false } },"infoEndpoint": { "prefix": "endpoints.info","properties": { "id": "info","sensitive": false,"enabled": true } } ... } beans 根据示例就可以看出,展示了bean的别名、类型、是否单例、类的地址、依赖等信息。 启动示例项目,访问: http://localhost:8088/monitor/beans 返回部分信息如下: [ { "context": "application:8080:management","parent": "application:8080","beans": [ { "bean": "embeddedServletContainerFactory","aliases": [ ],"scope": "singleton","type": "org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory","resource": "null","dependencies": [ ] },{ "bean": "endpointWebMvcChildContextConfiguration","type": "org.springframework.boot.actuate.autoconfigure.EndpointWebMvcChildContextConfiguration$$EnhancerBySpringCGLIB$$a4a10f9d","dependencies": [ ] } } ] dump /dump 接口会生成当前线程活动的快照。这个功能非常好,方便我们在日常定位问题的时候查看线程的情况。 主要展示了线程名、线程ID、线程的状态、是否等待锁资源等信息。 启动示例项目,访问: http://localhost:8088/monitor/dump 返回部分信息如下: [ { "threadName": "http-nio-8088-exec-6","threadId": 49,"blockedTime": -1,"blockedCount": 0,"waitedTime": -1,"waitedCount": 2,"lockName": "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1630a501","lockOwnerId": -1,"lockOwnerName": null,"inNative": false,"suspended": false,"threadState": "WAITING","stackTrace": [ { "methodName": "park","fileName": "Unsafe.java","lineNumber": -2,"className": "sun.misc.Unsafe","nativeMethod": true },{ "methodName": "park","fileName": "LockSupport.java","lineNumber": 175,"className": "java.util.concurrent.locks.LockSupport","nativeMethod": false },{ "methodName": "await","fileName": "AbstractQueuedSynchronizer.java","lineNumber": 2039,"className": "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject",... { "methodName": "getTask","fileName": "ThreadPoolExecutor.java","lineNumber": 1067,"className": "java.util.concurrent.ThreadPoolExecutor",{ "methodName": "runWorker","lineNumber": 1127,{ "methodName": "run","lineNumber": 617,"className": "java.util.concurrent.ThreadPoolExecutor$Worker","fileName": "TaskThread.java","lineNumber": 61,"className": "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable","fileName": "Thread.java","lineNumber": 745,"className": "java.lang.Thread","nativeMethod": false } ],"lockedMonitors": [ ],"lockedSynchronizers": [ ],"lockInfo": { "className": "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject","identityHashCode": 372286721 } } ... ] env 展示了系统环境变量的配置信息,包括使用的环境变量、JVM 属性、命令行参数、项目使用的jar包等信息。和configprops不同的是,configprops关注于配置信息,env关注运行环境信息。 启动示例项目,访问: http://localhost:8088/monitor/env 返回部分信息如下: { "profiles": [ ],"server.ports": { "local.management.port": 8088,"local.server.port": 8080 },"servletContextInitParams": { },"systemProperties": { "com.sun.management.jmxremote.authenticate": "false","java.runtime.name": "Java(TM) SE Runtime Environment","spring.output.ansi.enabled": "always","sun.boot.library.path": "C:Program FilesJavajdk1.8.0_101jrebin","java.vm.version": "25.101-b13","java.vm.vendor": "Oracle Corporation","java.vendor.url": "http://java.oracle.com/","java.rmi.server.randomIDs": "true","path.separator": ";","java.vm.name": "Java HotSpot(TM) 64-Bit Server VM","file.encoding.pkg": "sun.io","user.country": "CN","user.script": "","sun.java.launcher": "SUN_STANDARD","sun.os.patch.level": "","PID": "5268","com.sun.management.jmxremote.port": "60093","java.vm.specification.name": "Java Virtual Machine Spe 为了避免敏感信息暴露到 /env 里,所有名为password、secret、key(或者名字中最后一段是这些)的属性在 /env 里都会加上“*”。举个例子,如果有一个属性名字是database.password,那么它在/env中的显示效果是这样的: "database.password":"******" /env/{name}用法 就是env的扩展 可以获取指定配置信息,比如: http://localhost:8088/monitor/env/java.vm.version,返回: {"java.vm.version":"25.101-b13"} health 可以看到 HealthEndPoint 给我们提供默认的监控结果,包含 磁盘检测和数据库检测 启动示例项目,访问: http://localhost:8088/monitor/health 返回部分信息,下面的JSON响应是由状态、磁盘空间和db。描述了应用程序的整体健康状态,UP 表明应用程序是健康的。磁盘空间描述总磁盘空间,剩余的磁盘空间和最小阈值。 application.properties 阈值是可配置的 { "status": "UP","diskSpace": { "status": "UP","total": 209715195904,"free": 183253909504,"threshold": 10485760 } "db": { "status": "UP","database": "MySQL","hello": 1 } } 其实看 Spring Boot-actuator 源码,你会发现 HealthEndPoint 提供的信息不仅限于此,org.springframework.boot.actuate.health 包下 你会发现 ElasticsearchHealthIndicator、RedisHealthIndicator、RabbitHealthIndicator 等 info info就是我们自己配置在配置文件中以Info开头的配置信息,比如我们在示例项目中的配置是: info: app: name: spring-boot-actuator version: 1.0.0 启动示例项目,访问: http://localhost:8088/monitor/info 返回部分信息如下: { "app": { "name": "spring-boot-actuator","version": "1.0.0" } } mappings 描述全部的URI路径,以及它们和控制器的映射关系 启动示例项目,访问: http://localhost:8088/monitor/mappings 返回部分信息如下: { "/**/favicon.ico": { "bean": "faviconHandlerMapping" },"{[/hello]}": { "bean": "requestMappingHandlerMapping","method": "public java.lang.String com.neo.controller.HelloController.index()" },"{[/error]}": { "bean": "requestMappingHandlerMapping","method": "public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String,java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)" } } metrics 最重要的监控内容之一,主要监控了JVM内容使用、GC情况、类加载信息等。 启动示例项目,访问: http://localhost:8088/monitor/metrics 返回部分信息如下: { "mem": 337132,"mem.free": 183380,"processors": 4,"instance.uptime": 254552,"uptime": 259702,"systemload.average": -1.0,"heap.committed": 292864,"heap.init": 129024,"heap.used": 109483,"heap": 1827840,"nonheap.committed": 45248,"nonheap.init": 2496,"nonheap.used": 44269,"nonheap": 0,"threads.peak": 63,"threads.daemon": 43,"threads.totalStarted": 83,"threads": 46,"classes": 6357,"classes.loaded": 6357,"classes.unloaded": 0,"gc.ps_scavenge.count": 8,"gc.ps_scavenge.time": 99,"gc.ps_marksweep.count": 1,"gc.ps_marksweep.time": 43,"httpsessions.max": -1,"httpsessions.active": 0 } 对 /metrics 接口提供的信息进行简单分类如下表:
解释说明:
shutdown 开启接口优雅关闭Spring Boot应用,要使用这个功能首先需要在配置文件中开启: endpoints: shutdown: enabled: true 配置完成之后,启动示例项目,访问: http://localhost:8088/monitor/shutdown 返回部分信息如下: { "message": "Shutting down,bye..." } 此时你会发现应用已经被关闭。 trace /trace 接口能报告所有Web请求的详细信息,包括请求方法、路径、时间戳以及请求和响应的头信息,记录每一次请求的详细信息。 启动示例项目,先访问一次: http://localhost:8080/hello ,再到浏览器执行: http://localhost:8088/monitor/trace 查看返回信息: [ { "timestamp": 1516780334777,"info": { "method": "GET","path": "/hello","headers": { "request": { "host": "localhost:8080","connection": "keep-alive","cache-control": "max-age=0","user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.84 Safari/537.36","upgrade-insecure-requests": "1","accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","accept-encoding": "gzip,deflate,br","accept-language": "zh-CN,zh;q=0.9","cookie": "UM_distinctid=16053ba344f1cd-0dc220c44cc94-b7a103e-13c680-16053ba3450751; Hm_lvt_0fb30c642c5f6453f17d881f529a1141=1513076406,1514961720,1515649377; CNZZDATA1260945749=232252692-1513233181-%7C1516085149; Hm_lvt_6d8e8bb59814010152d98507a18ad229=1515247964,1515296008,1515672972,1516086283" },"response": { "X-Application-Context": "application:8080","Content-Type": "text/html;charset=UTF-8","Content-Length": "11","Date": "Wed,24 Jan 2018 07:52:14 GMT","status": "200" } },"timeTaken": "4" } } ] 上述信息展示了,/hello请求的详细信息。 其它配置 敏感信息访问限制 根据上面表格,鉴权为false的,表示不敏感,可以随意访问,否则就是做了一些保护,不能随意访问。 endpoints.mappings.sensitive=false 这样需要对每一个都设置,比较麻烦。敏感方法默认是需要用户拥有ACTUATOR角色,因此,也可以设置关闭安全限制: management.security.enabled=false 或者配合Spring Security做细粒度控制。 启用和禁用接口 虽然Actuator的接口都很有用,但你不一定需要全部这些接口。默认情况下,所有接口(除 了/shutdown)都启用。比如要禁用 /metrics 接口,则可以设置如下: endpoints.metrics.enabled = false 如果你只想打开一两个接口,那就先禁用全部接口,然后启用那几个你要的,这样更方便。 endpoints.enabled = false endpoints.metrics.enabled = true 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。 您可能感兴趣的文章:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |