【视频 & 交流平台】
http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
https://gitee.com/happyangellxq520/spring-boot
http://412887952-qq-com.iteye.com/blog/2321532
在上一篇博客中已经介绍了Endpoint的一个基本原理,这篇博客中看看如何自定义一个Endpoint,看下本章主要内容:
本章大纲:
(2)编码分析
(3)谈谈Runtime
(4)引入依赖
(5)编写内存实体类MemInfo
(6)编写EndPoint类
(7)编写EndPoint配置类
(8)编写启动类并且测试
(9)例子延伸
接下来看下具体的内容:
(1)例子说明
这里我们编写一个简单的获取内存的endpoint。
(2)编码分析
我们编写endpoint类大体的思路是:
(b)编写一个MyEndpoint实现endpoint,让MyEndpoint具有监控的属性。
(c)配置MyEndpoint。
(d)测试。
(3)谈谈Runtime
在这个例子中,我们要收集内存信息,那么要用到JDK提供的一个类叫Runtime,在这个类中可以获取到内存的使用情况。
(a)maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里获取到的最大的内存,以字节为单位,如果在运行java程序的时 候,没有添加-Xmx参数,那么就是64兆,也就是说maxMemory()返回的大约是64*1024*1024字节,这是java虚拟机默认情况下能 从操作系统那里获取到的最大的内存。如果添加了-Xmx参数,将以这个参数后面的值为准,例如java -cp ClassPath -Xmx512m ClassName,那么最大内存就是512*1024*0124字节。
(b)totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里获取到时内存大小,也就是java虚拟机这个进程当时所占用的所有内存。如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直 挖到maxMemory()为止,所以totalMemory()是慢慢增大的。如果用了-Xms参数,程序在启动的时候就会无条件的从操作系统中挖- Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。
(c)freeMemory()是什么呢,刚才讲到如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多获取一点的,这些获取而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行java程序的时候使用了-Xms,这个时候因为程序在启动的时候就会无条件的从操作系统中获取-Xms后面定义的内存数,这个时候获取到的内存可能大部分没用上,所以这个时候freeMemory()可 能会有些大。
(4)引入依赖
我们新建一个项目,取名为:spring-boot-endpoint,在pom.xml文件中引入相关依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kfit</groupId>
<artifactId>spring-boot-endpoint</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-endpoint</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--
spring boot 父节点依赖,
引入这个之后相关的引入就不需要添加version配置,
spring boot会自动选择最合适的版本进行添加。
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<!-- spring boot web支持:mvc,aop... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- actuator是spring boot提供的对应用系统的自省和监控的集成功能,可以对应用系统进行配置查看、相关功能统计等 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
(5)编写内存实体类MemInfo
编写一个实体类用于存储内存的基本信息:
class –-> com.kfit.bean.MenuInfo:
package com.kfit.bean; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; public class MemInfo { @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date recordTime;//记录时间. private long maxMemory;//能构从操作系统那里挖到的最大的内存,以字节为单位 private long totalMemory;//进程当时所占用的所有 内存 public Date getRecordTime() { return recordTime; } public void setRecordTime(Date recordTime) { this.recordTime = recordTime; } public long getMaxMemory() { return maxMemory; } public void setMaxMemory(long maxMemory) { this.maxMemory = maxMemory; } public long getTotalMemory() { return totalMemory; } public void setTotalMemory(long totalMemory) { this.totalMemory = totalMemory; } }
(6)编写EndPoint类
定义一个监控类,主要返回当前的内存信息和对外暴露访问地址。
class à com.kfit.endpoint.MyEndPoint :
package com.kfit.endpoint; import java.util.Date; import org.springframework.boot.actuate.endpoint.Endpoint; import com.kfit.bean.MemInfo; public class MyEndPoint implements Endpoint<MemInfo>{ /** * (1) getId是EndPoint的唯一标识, * (2)MVC接口对外暴露的路径:http://localhost:8080/myendpoint */ @Override public String getId() { return "myendpoint"; } @Override public boolean isEnabled() { return true; } @Override public boolean isSensitive() { return false; } @Override public MemInfo invoke() { MemInfo memInfo = new MemInfo(); Runtime runtime = Runtime.getRuntime(); memInfo.setRecordTime(new Date()); memInfo.setMaxMemory(runtime.maxMemory()); memInfo.setTotalMemory(runtime.totalMemory()); return memInfo; } }
getId()是Endpoint唯一的标识,另外也是MVC接口对外暴露的路径,以上代码对外访问路径就是:http://localhost:8080/myendpoint
(7)编写Endpoint配置类
编写Endpoint配置类EndPointAutoConfig发布MyEndpoint监控。
class - com.kfit.endpoint.EndPointAutoConfig :
package com.kfit.endpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class EndPointAutoConfig { @Bean public MyEndPoint myEndPoint() { return new MyEndPoint(); } }
(8)编写启动类并且测试
启动类没有什么特别之处,正常编码即可:
package com.kfit; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
启动应用程序进行测试,访问:http://localhost:8080/myendpoint ,返回如下信息:
{ recordTime: "2017-06-12 03:44:05", maxMemory: 1817706496, totalMemory: 198180864 }
(9)例子延伸
以上只是一个简单实用Endpoint的例子,实际没什么鸟用,在实际中,我们如果要收集内存信息的话,一定是希望想看到内存的一个变化情况,什么时间是20M,什么时候是25M了,最好还能够用折线图展现出来,所以我们可能要用一个List存储每个时间点的内存情况,这个时间点是怎么产生的呢?定时统计,比如我们可以每5秒统计一次。好了,博主就点到为止吧。
视频&交流平台:
http://study.163.com/course/introduction.htm?courseId=1004329008
http://412887952-qq-com.iteye.com/blog/2321532