SpringBoot第十二集:度量指标监控与异步调用(2020最新最易懂)
SpringBoot第十二集:度量指标监控与异步调用(2020最新最易懂)
Spring Boot Actuator
是spring boot
项目一个监控模块,提供了很多原生的端点,包含了对应用系统的自省和监控的集成功能,比如应用程序上下文里全部的Bean、运行状况检查、健康指标、环境变量及各类重要度量指标等等,以图形化界面的方式展示这些信息,通过这些监控信息,我们就能随时了解应用的运行情况了。
作用:可以通过监控运行状态检查获取应用的运行状态,潜在问题等。可以更具这些且在风险对项目进行优化,排除问题保证项目的运行。可以通过监控度量指标获取应用内存占用,线程数量,垃圾回收过程对项目进行深入分析。
一.Spring Boot Actuator的度量指标监控入门
1,准备工作
在项目中引入Actuator依赖,该以来由SprngBoot官方提供。
- 1 <dependency>
- 2 <groupId>org.springframework.boot</groupId>
- 3 <artifactId>spring-boot-starter-actuator</artifactId>
- 4 </dependency>
当项目中引入了Actuator依赖后,那么当前的项目就表示拥有了度量指标监控能力了,启动SpringBoot项目,控制台如下:
框起来的那段内容表示:SpringBoot监控已经默认暴露了两个基础端点,可供我们访问获取应用监控数据,基础访问路径是"/actuator"
2,访问基础端点测试
输入访问路径:localhost:8080/actuator 结果如下:(为便于查看,我已将JSON结果格式化)
- 1 {
- 2 "_links": {
- 3 "self": {
- 4 "href": "http://localhost:8080/actuator", // 基础访问地址
- 5 "templated": false
- 6 },
- 7 "health-path": {
- 8 "href": "http://localhost:8080/actuator/health/{*path}",
- 9 "templated": true
- 10 },
- 11 "health": {
- 12 "href": "http://localhost:8080/actuator/health", // 暴露的端点一 (访问URL)
- 13 "templated": false
- 14 },
- 15 "info": {
- 16 "href": "http://localhost:8080/actuator/info", // 暴露的端点二 (访问URL)
- 17 "templated": false
- 18 }
- 19 }
- 20 }
那么这些暴露的URL访问后分别代表什么呢?Actuator提供了13个接口,可以分为三大类:配置接口、度量接口和其它接口,具体如下表:
HTTP 方法 | 路径 | 描述 |
---|---|---|
GET | /autoconfig | 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过 |
GET | /configprops |
描述配置属性(包含默认值)如何注入Bean ●prefix属性代表 了属性的配置前缀 |
GET | /beans |
描述应用程序上下文里全部的Bean,以及它们的关系 ●bean:Bean的名称 |
GET | /dump | 获取线程活动的快照 |
GET | /env | 获取全部环境属性。包括:环境变量、JVM属性.应用的配置配置。命令行中的参数等 |
GET | /env/{name} | 根据名称获取特定的环境属性值。/env接口还能用来获取单个属性的值。只需要在请求时在/env/+属性名即可。 |
GET | /health | 报告应用程序的健康指标(运行状态),这些值由HealthIndicator的实现类提供.(默认暴露的接口) |
GET | /info |
获取应用程序的自定义的定制信息,这些信息由info打头的属性提供。默认情况下.该端点只会返回一个空的json内容,我们可以在application.properties配置文件中通过info前骚来设置一些属性(默认暴露的接口) |
GET | /mappings | 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系,罗列出应用程序发布的全部接口。
●bean属性标识了 该映射关系的请求处理器 |
GET | /metrics | 报告各种应用程序度量信息,比如内存用量,线程信息,垃圾回收信息,HTTP请求计数等 |
GET | /metrics/{name} | 报告指定名称的应用程序度量值 |
POST | /shutdown | 关闭应用程序,要求endpoints.shutdown.enabled设置为true |
GET | /trace | 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等) |
访问一个试试?localhost:8080/actuator/health 访问后结果:运行状态为正常运行(说明:Actuator监控获取的所有数据都是JSON格式的。)
- 1 {"status":"UP"}
那么如果希望访问其他接口怎么办?,默认只开启了info、health
两个端点,需要额外开启端点,需要额外去配置的!!!
- 1 #配置访问端点的根路径
- 2 management:
- 3 endpoints:
- 4 web:
- 5 # 配置访问端点的根路径,默认是/actuator
- 6 #base-path: /actuator
- 7 exposure:
- 8 #配置开启其他端点的URI,开启所有的端点访问: *,也可以指定开启端点访问:如: /beans, /env
- 9 include: "*"
- 10 # - /beans
- 11 # - /env
- 12 #配置排除其他端点的URI(排除即不开启)
- 13 #exclude:
- 14 # - /beans
- 15 # - /env
重启SpringBoot服务,如下:
具体访问测试就不演示了,Actuator监控获取的所有数据都是JSON格式的,可以自己访问测试后通过网络工具格式化JSON。
二.可视化UI界面实现监控应用
Actuator来监控Spring Boot应用,其提供了许多REST接口来查看应用的信息。但其返回的是大量的JSON格式数据,信息看上去不直观也不易于理解。Spring Boot Admin(SBA)是一款基于Actuator开发的开源软件(是一个针对spring-boot
的actuator
接口进行UI美化封装的监控工具),可以实现图形化界面的方式展示Spring Boot应用的配置信息、Beans信息、环境属性、线程信息、JVM状况等。官方说明文档点这里。选择版本文档说明,内有详情使用说明。
SpringBootAdmin的使用是需要建立服务端与客户端的。Spring Boot Admin
包含admin-server
与admin-client
两个组件,admin-server
通过采集actuator
端点数据,显示在spring-boot-admin-ui
上。
服务端:独立的项目,会将搜集到的数据在自己的图形界面中展示。依赖admin-server
客户端:需要监控的项目。依赖Actuator,admin-client
对应关系:一个服务端可以监控多个客户端。
1.建立Spring Boot Admin Server服务端
温馨提示:服务端属于一个独立SpringBoot的项目(新建项目)。
- 新建SpringBoot项目(当前版本2.4.0)。
- 修改pom引入SpringBootAdmin-Server依赖。
既然是一个服务端,那肯定是需要启动容器(Tomcat)的,所以具体的依赖,你看情况添加(可以选择根据SpringBoot新建项目时勾选依赖,也可以从Maven中查找)
- 1 <!-- spring-boot-admin-服务端依赖 -->
- 2 <dependency>
- 3 <groupId>de.codecentric</groupId>
- 4 <artifactId>spring-boot-admin-starter-server</artifactId>
- 5 <version>2.3.1</version>
- 6 </dependency>
- 1 <!-- spring-boot-admin-服务端依赖 -->
- 修改yml配置文件
毕竟服务端属于一个独立SpringBoot的项目,管理的客户端也是一个独立的项目,如果不更改端口,可能端口会出现占用情况,所以更新配置文件修改端口
- 1 server:
- 2 #servlet:
- 3 # 配置访问路径(可选)
- 4 #context-path: /admin-server
- 5 # 配置端口
- 6 port: 9090
- 1 server:
- 启动类添加注解@EnableAdminServer
开启SpringBootAdmin-Server服务端
- 1 @SpringBootApplication
- 2 @EnableAdminServer
- 3 public class SpringbootAdminServerApplication {
- 1 @SpringBootApplication
- 启动服务访问
http://localhost:9090/ 效果图如下因为还没添加客户端,所以监控列表里是空的,接下来创建一个Spring Boot应用作为客户端。
1.建立Spring Boot Admin Client客户端
admin-server
通过采集actuator
端点数据,将信息解析展示在UI界面的。那么客户端就需要依赖Actuator和admin-clietn。
- 修改pom引入admin-client依赖
本次案例演示,直接在前面的Actuator项目中更新- 1 <!-- spring-boot-admin-starter-client客户端依赖:注意要与服务端版本一致 -->
- 2 <dependency>
- 3 <groupId>de.codecentric</groupId>
- 4 <artifactId>spring-boot-admin-starter-client</artifactId>
- 5 <version>${spring-boot-admin.version}</version>
- 6 </dependency>
注意:1.版本要与服务端一致。2.客户端项目依赖不能少了Actuator。
- 1 <!-- spring-boot-admin-starter-client客户端依赖:注意要与服务端版本一致 -->
- 修改yml文件添加必须配置
更多配置及应用参考:Spring-Boot-Admin官方文档- 1 #配置访问端点的根路径
- 2 management:
- 3 endpoints:
- 4 web:
- 5 # 配置访问端点的根路径,默认是/actuator
- 6 #base-path: /actuator
- 7 exposure:
- 8 #配置开启其他端点的URI,开启所有的端点访问: *,也可以指定开启端点访问:如: /beans, /env
- 9 include: "*"
- 10 # - /beans
- 11 # - /env
- 12 #配置排除其他端点的URI(排除即不开启)
- 13 #exclude:
- 14 # - /beans
- 15 # - /env
- 16
- 17 spring:
- 18 boot:
- 19 admin:
- 20 client:
- 21 # 配置客户端,被监控的服务端地址(官方说明也很详细的,这个是必须配置的)
- 22 url:
- 23 - http://localhost:9090
- 1 #配置访问端点的根路径
- 启动客户端项目
之前服务端启动后,项目监控为0,当这个客户端启动后,需要稍等片刻,重新请求访问服务端地址(http://localhost:9090),即可看到如下:点击左上“应用墙”进入SpringBootAdmin主页,显示运行时间,项目个数。点击进入详情页,即可已图形报表UI界面方式显示所有监控信息:
如上的操作更多的可能是涉及到了测试/运维的问题,所以这里就不深究了,但某些时候需要我们开发人员配和实现更多操作,例如邮件方式发送检测日志,信息等。详情参考SpringBootAdmin
二,SpringBoot中的异步调用
实际开发中,有一些业务可能和实际业务无关,但又不能没有,例如:注册新用户,立即送积分(没有点击领取但积分已到账),或下单成功,发送push消息等等。
通常我们开发的程序都是同步调用的,即程序按照代码的顺序一行一行的逐步往下执行,每一行代码都必须等待上一行代码执行完毕才能开始执行。而异步编程则没有这个限制,代码的调用不再是阻塞的。所以在一些情景下,通过异步编程可以提高效率,提升接口的吞吐量。
使用异步的好处?就拿注册用户送积分来说:
- 容错性。(不能因为积分赠送失败,导致用户注册不成功!)
注册用户是主要业务,积分赠送失败,可以在提供有针对性的异常补偿! - 提升性能和接口吞吐量
用户注册,需要20s,送积分需要10s,如果同步调用,则用户需要等待30s,如果异步调用,用户只需要消耗20s即可注册成功。
1.没有异步调用代码测试
不使用异步调用,即同步调用测试。
- 编写Service提供两个方法,一个实现注册,一个实现送积分。
为便于清晰测试,在积分方法中使用线程休眠。- 1 @Service
- 2 public class AsynService {
- 3
- 4 /**
- 5 * 注册方法
- 6 */
- 7 public void register() {
- 8 System.out.println("注册成功.......");
- 9 }
- 10 /**
- 11 * 异步方法送积分
- 12 */
- 13 public void asynIntegral() {
- 14 try {
- 15 Thread.sleep(3000);// 休息三秒
- 16 } catch (InterruptedException e) {
- 17 // TODO Auto-generated catch block
- 18 e.printStackTrace();
- 19 }
- 20 System.out.println("送积分100分....执行者线程名为:"+Thread.currentThread().getName());
- 21 }
- 22
- 23 }
- 1 @Service
- 编写Controoler注册功能,在注册后调用送积分方法。
- 1 @RestController
- 2 @Slf4j // 获取log对象,Lombok插件中的注解
- 3 public class AsynController {
- 4
- 5 @Autowired
- 6 private AsynService asynService;
- 7
- 8 @RequestMapping("/register")
- 9 public String asynTest() {
- 10 long startTmie = System.currentTimeMillis();
- 11 // 注册逻辑:调用注册方法
- 12 asynService.register();
- 13 // 调用送积分方法
- 14 asynService.asynIntegral();
- 15 long endtTmie = System.currentTimeMillis();
- 16 log.info("消耗时间:"+(endTime-starttTmie));
- 17 return "ok";
- 18 }
- 19
- 20 }
- 1 @RestController
- 页面测试访问,查看控制台运行总耗时.
localhost:8080/register
- 注册成功.......
- 送积分100分....执行者线程名称为:http-nio-8080-exec-1
- 2020-12-02 20:00:15.112 INFO 4604 --- [nio-8080-exec-1] c.xsge123.app.controller.AsynController : 消耗时间:3002
结束语:在同步调用时,页面不会立刻刷新注册结果,只有注册和送积分的功能全部执行完成后,页面才会显示注册通知。客户需等待较长的时间。程序总耗时较长。
- 注册成功.......
2,异步调用代码测试
在同步代码基础上,新增配置类AsyncConfig,配置开启异步调用,同时在需要使用异步调用的方法上使用注解@Async即可。
- 新增配置类AsyncConifg,使用注解@EnableAsync开启异步调用 ,并将配置类加入到Spring容器中。
准确的说注解@EnableAsync直接在SpringBoot启动类上使用即可。那么这个新增配置类的意义何在呢?SpringBoot异步调用的实质是,为异步调用方法开启了新的线程(提供这个配置类,是为了便于后面自定义线程池的)当然如果不考虑自定义线程池,则可以直接选择在SpringBoot启动类上使用注解,这样就可以省略配置类了。但程序....你细品。- 1 @Configuration // 将类注入到Spring容器中
- 2 @EnableAsync //开启SpringBoot异步调用(针对异步调用的方法,开启新线程),在启动类上使用也可以
- 3 public class AsyncConfig {
- 4
- 5 }
- 1 @Configuration // 将类注入到Spring容器中
- 在需要异步调用的业务方法上使用注解@Aynsc,表示当前方法为异步方法
- 1 /**
- 2 * 异步方法送积分
- 3 */
- 4 @Async // 标注当前方法为异步方法
- 5 public void asynIntegral() {
- 6 try {
- 7 Thread.sleep(3000);// 休息3秒
- 8 } catch (InterruptedException e) {
- 9 // TODO Auto-generated catch block
- 10 e.printStackTrace();
- 11 }
- 12 System.out.println("送积分100分...."+Thread.currentThread().getName());
- 13 }
- 1 /**
- 启动服务测试,查看控制台耗时。
localhost:8080/register
- 注册成功.......
- 2020-12-02 20:18:11.764 INFO 4604 --- [nio-8080-exec-2] c.xsge123.app.controller.AsynController : 消耗时间:6
- 送积分100分....task-1
送积分100分....score-2
送积分100分....score-3
结束语:在异步调用的情况下,页面即刻响应注册结果,无需等待,后台等待3秒后,送积分程序显示执行结果。
- 注册成功.......
3,自定义异步调用线程池
@Async注解,在默认情况下,用的是SimpleAsyncTaskExecutor线程池,该线程池不是真正意义上的线程池,因为线程不可重用,每次调用都会新建一条线程。可以通过控制台日志输出查看,每次打印的线程名都是[task -1]、[task -2]、[task-3]、[task-4].....递增的。
@Async注解异步框架提供有多种线程池支持:
SimpLeAsyncTaskExecutor:不是真的线程池,这个类不可重用线程,每次调用都会创建一个新的线程 。
SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作。只适用于不需要多线程的地方
ConcurrentTaskExecutor:Executor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类
ThreadPoolTaskScheduler:可以使用cron表达式。
ThreadPoolTaskExecutor :最常使用,推荐。 其实质是对java.util.concurrent .ThreadPoolExecutor的包装类。
- 修改AsyncConfig配置类,添加自定义线程池方法,注入bean
- 1 @Configuration // 将类注入到Spring容器中
- 2 @EnableAsync //开启SpringBoot异步调用(针对异步调用的方法,开启新线程)
- 3 public class AsyncConfig {
- 4
- 5 @Bean(name = "scorePoolTaskExecutor")
- 6 public ThreadPoolTaskExecutor getScorePoolTaskExecutor() {
- 7 // 创建线程池对象
- 8 ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
- 9 //核心线程数
- 10 taskExecutor.setCorePoolSize(10);
- 11 //线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
- 12 taskExecutor.setMaxPoolSize(100);
- 13 //缓存队列
- 14 taskExecutor.setQueueCapacity(50) ;
- 15 //许的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
- 16 taskExecutor.setKeepAliveSeconds (200) ;
- 17 //.异步方法内部线程名称
- 18 taskExecutor.setThreadNamePrefix("score-");
- 19 /**
- 20 * 当线程池的任务缓存队列已满,并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
- 21 * 通常有以下四种策略:
- 22 * ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecuti onException异常。
- 23 * ThreadPoolExecutor.DiscardPolicy: 也是丢弃任务,但是不抛出异常。
- 24 * ThreadPoolExecutor. DiscardOldestPolicy: 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
- 25 * ThreadPoolExecutor . CallerRunsPolicy:重试添加当前的任务,自动重复调用execute()方法,直到成功
- 26 */
- 27 taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
- 28 taskExecutor.initialize() ;
- 29 return taskExecutor;
- 30 }
- 31
- 32 }
- 1 @Configuration // 将类注入到Spring容器中
- 修改注解@Async的使用,在使用注解时,指定使用的自定义线程
- 1 /**
- 2 * 异步方法送积分
- 3 */
- 4 @Async("scorePoolTaskExecutor") // 标注当前方法为异步方法
- 5 public void asynIntegral() {
- 6 try {
- 7 Thread.sleep(3000);
- 8 } catch (InterruptedException e) {
- 9 // TODO Auto-generated catch block
- 10 e.printStackTrace();
- 11 }
- 12 System.out.println("送积分100分...."+Thread.currentThread().getName());
- 13 }
- 1 /**
- 启动服务,测试自定义线程池实现异步调用,查看控制台结果
- 注册成功.......
- 2020-12-02 20:45:57.898 INFO 4604 --- [nio-8080-exec-3] c.xsge123.app.controller.AsynController : 消耗时间:2
- 送积分100分....score-1
- 送积分100分....score-2
- 送积分100分....score-3
结束语:线程实现自定义
- 注册成功.......
SpringBoot第十二集:度量指标监控与异步调用(2020最新最易懂)的更多相关文章
- SpringBoot第三集:热部署与单元测试(2020最新最易懂)
SpringBoot第三集:热部署与单元测试(2020最新最易懂) 有兴趣的可以先参考附录简单了解SpringBoot自动装配流程. 一.SpringBoot开发热部署 项目开发中,你是否也遇到更新配 ...
- SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂)
SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂) 当前环境说明: Windows10_64 Maven3.x JDK1.8 MySQL5.6 SpringTool ...
- SpringBoot第五集:整合Druid和MyBatis(2020最新最易懂)
SpringBoot第五集:整合Druid和MyBatis(2020最新最易懂) 1.SpringBoot整合Druid Druid是阿里巴巴的一个开源项目,是一个数据库连接池的实现,结合了C3P0. ...
- SpringBoot第二十二篇:应用监控之Actuator
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11226397.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 很多文章都 ...
- SpringBoot第二十四篇:应用监控之Admin
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 前一章(S ...
- SpringBoot第二集:注解与配置(2020最新最易懂)
2020最新SpringBoot第二集:基础注解/基础配置(2020最新最易懂) 一.Eclipse安装SpringBoot插件 Eclipse实现SpringBoot开发,为便于项目的快速构建,需要 ...
- SpringBoot第十集:i18n与Webjars的应用(2020最新最易懂)
SpringBoot第十集:i18n与Webjars的应用(2020最新最易懂) 一,页面国际化 i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符 ...
- SpringBoot第一集:入门(2020最新最易懂)
2020最新SpringBoot第一集:入门(2020最新最易懂) 学习思路: 是什么?为什么要学,有什么用?有什么特点?简单明了的总结一句话! SpringBoot推荐开发工具: Spring To ...
- SpringBoot第五集:整合监听器/过滤器和拦截器(2020最新最易懂)
SpringBoot第五集:整合监听器/过滤器和拦截器(2020最新最易懂) 在实际开发过程中,经常会碰见一些比如系统启动初始化信息.统计在线人数.在线用户数.过滤敏/高词汇.访问权限控制(URL级别 ...
随机推荐
- 关于Linux操作系统的文件管理与常用命令
1.显示文件内容命令:cat more less head tail cat命令 : cat命令连接文件并打印到标准输出设备上,cat经常用来显示文件的内容,类似于下的 ...
- DP百题练(三)
目录 DP百题练(三) DP百题练(三) 不知不觉也刷了 50 道 DP 题了,感觉确实有较大的进步.(2020.3.20) 这里的 (三) 主要用来记录 DP 的各种优化(倍增.数据结构.斜率.四边 ...
- 2018-12-7 CSAPP及C++
今天虽然起床迟,但从结果上来看,学习效率还算不赖.从这几天的状况来看,为记录晚上上床后的学习内容,决定把在床上的学习内容算在后一天的学习中.那么从现在开始就可以协商英语的半个小时100个单词了. 英语 ...
- Docker 基础 B站 学习 最强 教程
狂神说!! https://www.bilibili.com/video/BV1og4y1q7M4
- 数据库会话数量过多,定期清理inactive会话
1.1现象 存在一套11.2.0.4 RAC 2节点,数据库存在5000个会话数量,其中active正在执行的会话500个,其余均为非活跃会话. 大量inactive会话过多给Oracle数据库带来什 ...
- Ubuntu 18.04 Tomcat 端口号查询
参考http://blog.csdn.net/liufuwu1/article/details/71123597 最近几天发现许多这篇笔记被许多朋友访问,推测有很多朋友也与我有相同的疑惑,而原始版本过 ...
- NIO源码分析:SelectionKey
SelectionKey SelectionKey,选择键,在每次通道注册到选择器上时都会创建一个SelectionKey储存在该选择器上,该SelectionKey保存了注册的通道.注册的选择器.通 ...
- Spring Security验证,提示正确的信息
关于Spring Security的使用,之前也整理过一些笔记,但是在提示信息的时候,总感觉还缺点什么?不管是不是前后端分离,我们都希望在登录验证出现错误的时候,能够提示友好的中文信息. 在前后端不分 ...
- axios封装接口
我们一般都是在做一个大型项目的时候,需要用到很多接口时,我们为了方便使用,就把接口封装起来. 先安装axios命令 :npm install axios --save 那么思路是什么呢? 首先在src ...
- jupyter使用自动补全和切换默认浏览器
自动补全 可以做conda环境中执行以下命令.linux下打开conda环境的命令是: conda activate 退出conda环境的命令是: conda deactivate 安装插件: pip ...