7.1.2 运行时度量
你到医生那里体检时,会做一系列检查来了解身体状况。有一些重要的项目永远不会变,比如血型。这类测试能让医生了解你身体的一贯情况。其他测试让医生掌握你接受检查时的身体状况。你的心律、血压和胆固醇水平有助于医生评估你的健康。这些指标都是临时的,很可能随时间发生变化,但它们同样是很有帮助的运行时指标。
与之类似,对运行时度量情况做一个快照,这对评估应用程序的健康情况很有帮助。Actuator 提供了一系列端点,让你能在运行时快速检查应用程序。让我们来了解一下这些端点,从/metrics 开始。
1. 查看应用程序的度量值
关于运行中的应用程序,有很多有趣而且有用的信息。举个例子,了解应用程序的内存情况(可用或空闲)有助于决定给 JVM 分配多少内存。对 Web 应用程序而言,不用查看 Web 服务器日志,如果请求失败或者是耗时太长,就可以大概知道内存的情况了。
运行中的应用程序有诸多计数器和度量器,/metrics 端点提供了这些东西的快照。代码清单 7-6 是/metrics 端点输出内容的示例。
代码清单 7-6 /metrics 端点提供了很多有用的运行时数据
{
mem: 198144,
mem.free: 144029,
processors: 8,
uptime: 1887794,
instance.uptime: 1871237,
systemload.average: 1.33251953125,
heap.committed: 198144,
heap.init: 131072,
heap.used: 54114,
heap: 1864192,
threads.peak: 21,
threads.daemon: 19,
threads: 21,
classes: 9749,
classes.loaded: 9749,
classes.unloaded: 0,
gc.ps_scavenge.count: 22,
gc.ps_scavenge.time: 122,
gc.ps_marksweep.count: 2,
gc.ps_marksweep.time: 156,
httpsessions.max: -1,
httpsessions.active: 1,
datasource.primary.active: 0,
datasource.primary.usage: 0,
counter.status.200.beans: 1,
counter.status.200.env: 1,
counter.status.200.login: 3,
counter.status.200.metrics: 2,
counter.status.200.root: 6,
counter.status.200.star-star: 9,
counter.status.302.login: 3,
counter.status.302.logout: 1,
counter.status.302.root: 5,
gauge.response.beans: 169,
gauge.response.env: 165,
gauge.response.login: 3,
gauge.response.logout: 0,
gauge.response.metrics: 2,
gauge.response.root: 11,
gauge.response.star-star: 2
}
如你所见,/metrics 端点提供了很多信息,逐行查看这些度量值太麻烦。表 7-2 根据所提供信息的类型对它们做了个分类。
表 7-2 /metrics 端点报告的度量值和计数器
分类 | 前缀 | 报告内容 |
---|---|---|
垃圾收集器 |
| 已经发生过的垃圾收集次数,以及垃圾收集所 |
内存 |
| 分配给应用程序的内存数量和空闲的内存数量 |
堆 |
| 当前内存用量(数据源自 |
类加载器 |
| JVM 类加载器加载与卸载的类的数量(数据源自 |
系统 |
| 系统信息,例如处理器数量(数据源自 |
线程池 |
| 线程、守护线程的数量,以及 JVM 启动后的线程数量峰值(数据源自 |
数据源 |
| 数据源连接的数量(源自数据源的元数据,仅当 Spring 应用程序上下文里存在 |
Tomcat 会话 |
| Tomcat 的活跃会话数和最大会话数(数据源自嵌入式 Tomcat 的 Bean,仅在使用嵌入式 Tomcat 服务器运行应用程序时才有这个信息) |
HTTP |
| 多种应用程序服务 HTTP 请求的度量值与计数器 |
请注意,这里的一些度量值,比如数据源和 Tomcat 会话,仅在应用程序中运行特定组件时才有数据。你还可以注册自己的度量信息,7.4.3 节里会提到这一点。
HTTP 的计数器和度量值需要做一点说明。counter.status 后的值是 HTTP 状态码,随后是所请求的路径。举个例子, counter.status.200.metrics
表明/metrics 端点返回 200(OK)状态码的次数。
HTTP 的度量信息在结构上也差不多,却在报告另一类信息。它们全部以 gauge.response 开头,表明这是 HTTP 响应的度量信息。前缀后是对应的路径。度量值是以毫秒为单位的时间,反映了最近处理该路径请求的耗时。举个例子,代码清单 7-6 里的 gauge.response.beans
说明上一次请求耗时 169 毫秒。
这里还有几个特殊的值需要注意。root 路径指向的是根路径或 /
。star-star 代表了那些 Spring 认为是静态资源的路径,包括图片、JavaScript 和样式表,其中还包含了那些找不到的资源。这就是为什么你经常会看到 counter.status.404.star-star
,这是返回了 HTTP 404 (NOT FOUND) 状态的请求数。
/metrics 端点会返回所有的可用度量值,但你也可能只对某个值感兴趣。要获取单个值,请求时可以在 URL 后加上对应的键名。例如,要查看空闲内存大小,可以向/metrics/mem.free 发一个 GET
请求:
$ curl localhost:8080/metrics/mem.free
144029
要知道,虽然响应里的 Content-Type
头设置为 application/json;charset=UTF-8,但实际/metrics/{name}的结果是文本格式的。因此,如果需要的话,你也可以把它视为 JSON 来处理。
2. 追踪 Web 请求
尽管/metrics 端点提供了一些针对 Web 请求的基本计数器和计时器,但那些度量值缺少详细信息。知道所处理请求的更多信息是很有帮助的,尤其是在调试时,所以就有了/trace 这个端点。
/trace 端点能报告所有 Web 请求的详细信息,包括请求方法、路径、时间戳以及请求和响应的头信息。代码清单 7-7 是/trace 输出的一个片段,其中包含了整个请求跟踪项。
代码清单 7-7 /trace 端点会记录下 Web 请求的细节
[
...
{
"timestamp": 1426378239775,
"info": {
"method": "GET",
"path": "/metrics",
"headers": {
"request": {
"accept": "*/*",
"host": "localhost:8080",
"user-agent": "curl/7.37.1"
},
"response": {
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Cache-Control":
"no-cache, no-store, max-age=0, must-revalidate",
"Pragma": "no-cache",
"Expires": "0",
"X-Frame-Options": "DENY",
"X-Application-Context": "application",
"Content-Type": "application/json;charset=UTF-8",
"Transfer-Encoding": "chunked",
"Date": "Sun, 15 Mar 2015 00:10:39 GMT",
"status": "200"
}
}
}
}
]
正如 method
和 path
属性所示,你可以看到这个跟踪项是一个针对/metrics 的请求。 timestamp
属性(以及响应中的 Date
头)告诉了你请求的处理时间。 headers
属性的内容是请求和响应中所携带的头信息。
虽然代码清单 7-7 里只显示了一条跟踪项,但/trace 端点实际能显示最近 100 个请求的信息,包含对/trace 自己的请求。它在内存里维护了一个跟踪库。稍后在 7.4.4 节里,你会看到如何创建一个自定义的跟踪库实现,以便将请求的跟踪持久化。
3. 导出线程活动
在确认应用程序运行情况时,除了跟踪请求,了解线程活动也会很有帮助。/dump 端点会生成当前线程活动的快照。
完整的线程导出报告里会包含应用程序的每个线程。为了节省空间,代码清单 7-8 里只放了一个线程的内容片段。如你所见,其中包含很多线程的特定信息,还有线程相关的阻塞和锁状态。本例中,还有一个跟踪栈(stack trace),表明这是一个 Tomcat 容器线程。
代码清单 7-8 /dump 端点提供了应用程序线程的快照
[
{
"threadName": "container-0",
"threadId": 19,
"blockedTime": -1,
"blockedCount": 0,
"waitedTime": -1,
"waitedCount": 64,
"lockName": null,
"lockOwnerId": -1,
"lockOwnerName": null,
"inNative": false,
"suspended": false,
"threadState": "TIMED_WAITING",
"stackTrace": [
{
"className": "java.lang.Thread",
"fileName": "Thread.java",
"lineNumber": -2,
"methodName": "sleep",
"nativeMethod": true
},
{
"className": "org.springframework.boot.context.embedded.
tomcat.TomcatEmbeddedServletContainer$1",
"fileName": "TomcatEmbeddedServletContainer.java",
"lineNumber": 139,
"methodName": "run",
"nativeMethod": false
}
],
"lockedMonitors": [],
"lockedSynchronizers": [],
"lockInfo": null
},
...
]
4. 监控应用程序健康情况
如果你想知道自己的应用程序是否在运行,可以直接访问/health 端点。在最简单的情况下,该端点会显示一个简单的 JSON,内容如下:
{"status":"UP"}
status
属性显示了应用程序在运行中。当然,它的确在运行,此处的响应无关紧要,任何输出都说明这个应用程序在运行。但/health 端点可以输出的信息远远不止简单的 UP
状态。
/health 端点输出的某些信息可能涉及内容,因此对未经授权的请求只能提供简单的健康状态。如果经过身份验证(比如你已经登录了),则可以提供更多信息。下面是阅读列表应用程序一些健康信息的示例:
{
"status":"UP",
"diskSpace": {
"status":"UP",
"free":377423302656,
"threshold":10485760
},
"db":{
"status":"UP",
"database":"H2",
"hello":1
}
}
除了基本的健康状态,可用的磁盘空间以及应用程序正在使用的数据库状态也可以看到。
/health 端点所提供的所有信息都是由一个或多个健康指示器提供的。表 7-3 列出了 Spring Boot 自带的健康指示器。
表 7-3 Spring Boot 自带的健康指示器
健康指示器 | 键 | 报告内容 |
---|---|---|
|
| 永远为 |
|
| 如果数据库能连上,则内容是 |
|
| 如果可用空间大于阈值,则内容为 |
|
| 如果能连上消息代理,则内容为 |
|
| 如果能连上邮件服务器,则内容为 |
|
| 如果能连上 MongoDB 服务器,则内容为 |
|
| 如果能连上 RabbitMQ 服务器,则内容为 |
|
| 如果能连上服务器,则内容为 |
|
| 如果能连上 Solr 服务器,则内容为 |
这些健康指示器会按需自动配置。举例来说,如果 Classpath 里有 javax.sql.DataSource
,则会自动配置 DataSourceHealthIndicator
。 ApplicationHealthIndicator
和 DiskSpaceHealthIndicator
则会一直配置着。
除了这些自带的健康指示器,你还会在 7.4.5 节里看到如何创建自定义健康指示器。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论