写点什么

SpringBoot:定制 -Actuator,深入 java 虚拟机百度网盘

用户头像
极客good
关注
发布于: 刚刚

endpoints:shutdown:id: kill


重命名端点、修改其路径的理由很多。最明显的理由就是,端点的命名要和团队的术语保持一致。你也可能想重命名端点,让那些熟悉默认名称的人找不到它,借此增加一些安全感。


遗憾的是,重命名端点并不能真的起到保护作用,顶多是让黑客慢点找到它们。现在先让我们来看看如何禁用某个(或全部)不希望别人访问的端点。

二、启用和禁用端点

虽然Actuator的端点都很有用,但你不一定需要全部这些端点。默认情况下,所有端点(除了/shutdown)都启用。这里就不详细介绍如何设置endpoints.shutdown.enabled为 true,以此开启/shutdown端点。用同样的方式,你可以禁用其他的端点,将endpoints. endpoint-id.enabled设置为 false。


例如,要禁用/metrics端点,你要做的就是将endpoints.metrics.enabled属性设置为 false。在application.yml里做如下设置:


endpoints:metrics:enabled: false


如果你只想打开一两个端点,那就先禁用全部端点,然后启用那几个你要的,这样更方便。例如,考虑如下application.yml片段:


endpoints:enabled: falsemetrics:enabled: true


正如以上片段所示,endpoints.enabled设置为 false 就能禁用 Actuator 的全部端点,然后将endpoints.metrics.enabled设置为 true 重新启用/metrics端点。

三、添加自定义度量信息

你可能还想定义自己的度量,用来捕获应用程序中的特定信息。


比方说,我们想要知道用户往阅读列表里保存了多少次图书,最简单的方法就是在每次调用ReadingListControlleraddToReadingList()方法时增加计数器值。计


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


数器很容易实现,但这个不断变化的总计值如何同/metrics端点发布的度量信息一起发布出来呢?


再假设我们想要获得最后保存图书的时间戳。时间戳可以通过调用System.currentTime-Millis()来获取,但如何在/metrics端点里报告该时间戳呢?


实际上,自动配置允许 Actuator 创建CounterService的实例,并将其注册为 Spring 的应用程序上下文中的 Bean。CounterService这个接口里定义了三个方法,分别用来增加、减少或重置 特定名称的度量值,代码如下:


package org.springframework.boot.actuate.metrics;public interface CounterService {void increment(String metricName);void decrement(String metricName);void reset(String metricName);}


Actuator 的自动配置还会配置一个GaugeService类型的 Bean。该接口与CounterService类似,能将某个值记录到特定名称的度量值里。GaugeService看起来是这样的:


package org.springframework.boot.actuate.metrics;public interface GaugeService {void submit(String metricName, double value);}


你无需实现这些接口。Spring Boot 已经提供了两者的实现。我们所要做的就是把它们的实例注入所需的 Bean,在适当的时候调用其中的方法,更新想要的度量值。


针对上文提到的需求,我们需要把CounterServiceGaugeService Bean注入Reading-ListController,然后在addToReadingList()方法里调用其中的方法。


使用注入的CounterServiceGaugeService


@Controller@RequestMapping("/")@ConfigurationProperties("amazon")public class ReadingListController {...private CounterService counterService;@Autowiredpublic ReadingListController(ReadingListRepository readingListRepository,AmazonProperties amazonProperties,CounterService counterService,GaugeService gaugeService) {this.readingListRepository = readingListRepository;this.amazonProperties = amazonProperties;this.counterService = counterService;this.gaugeService = gaugeService;}...@RequestMapping(method=RequestMethod.POST)public String addToReadingList(Reader reader, Book book) {book.setReader(reader);readingListRepository.save(book);counterService.increment("books.saved");gaugeService.submit("books.last.saved", System.currentTimeMillis());return "redirect:/";}}


修改后的ReadingListController使用了自动织入机制,通过控制器的构造方法注入CounterServiceGaugeService,随后把它们保存在实例变量里。此后,addToReading-List()方法每次处理请求时都会调用counterService.increment ("books.saved")gaugeService.submit("books. last.saved")来调整度量值。


尽管CounterServiceGaugeService用起来很简单,但还是有一些度量值很难通过增加计数器或记录指标值来捕获。对于那些情况,我们可以实现PublicMetrics接口,提供自己需要的度量信息。该接口定义了一个metrics()方法,返回一个 Metric 对象的集合:


package org.springframework.boot.actuate.endpoint;public interface PublicMetrics {Collection<Metric<?>> metrics();}


为了解PublicMetrics的使用方法,这里假设我们想报告一些源自 Spring 应用程序上下文的度量值——应用程序上下文启动的时间、Bean 及 Bean 定义的数量,这些都包含进来会很有意思。 顺便再报告一下添加了 @Controller 注解的 Bean 的数量。


发布自定义度量信息


package readinglist;import java.util.ArrayList;import java.util.Collection;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.actuate.endpoint.PublicMetrics;import org.springframework.boot.actuate.metrics.Metric;import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Component;import org.springframework.stereotype.Controller;@Componentpublic class ApplicationContextMetrics implements PublicMetrics {private ApplicationContext context;@Autowiredpublic ApplicationContextMetrics(ApplicationContext context) {this.context = context;}@Overridepublic Collection<Metric<?>> metrics() {List<Metric<?>> metrics = new ArrayList<Metric<?>>();metrics.add(new Metric<Long>("spring.context.startup-date",context.getStartupDate()));metrics.add(new Metric<Integer>("spring.beans.definitions",context.getBeanDefinitionCount()));metrics.add(new Metric<Integer>("spring.beans",context.getBeanNamesForType(Object.class).length));metrics.add(new Metric<Integer>("spring.controllers",context.getBeanNamesForAnnotation(Controller.class).length));return metrics;}}


Actuator 会调用metrics()方法,收集ApplicationContextMetrics提供的度量信息。该方法调用了所注入的ApplicationContext上的方法,获取我们想要报告为度量的数量。每个度量值都会创建一个Metrics实例,指定度量的名称和值,将其加入要返回的列表。


创建ApplicationContextMetrics,并在ReadingListController里使用Counter-ServiceGaugeService之后,我们可以在/metrics端点的响应中找到如下条目:


{...spring.context.startup-date: 1429398980443,spring.beans.definitions: 261,spring.beans: 272,spring.controllers: 2,books.count: 1,gauge.books.save.time: 1429399793260,...}


当然,这些度量的实际值会根据添加了多少书、何时启动应用程序及何时保存最后一本书而发生变化。在这个例子里,你一定会好奇为什么 spring.controllers 是 2。因为这里算上了ReadingListController以及 Spring Boot 提供的BasicErrorController

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
SpringBoot:定制-Actuator,深入java虚拟机百度网盘