服务器监控功能(3种方案)

家电修理 2023-07-16 19:17www.caominkang.com电器维修

服务器监控功能(3种方案)
        • 一、Actuator监控
          • 1. 添加依赖
          • 2. application.yaml配置
          • 3. 启动项目,访问
        • 二、SpringBoot Admin(单体)
          • 1. Admin Server 端
          • 2. Admin Client 端
        • 三、OSHI
          • 1. pom.xml依赖
          • 2. 接口返回数据
          • 3. 代码
一、Actuator监控

Actuator是Springboot提供的用来对应用系统进行自省和监控的功能模块,借助于Actuator开发者可以很方便地对应用系统某些监控指标进行查看、统计等。

部署简单、直接调接口拿值、数据较分散,需处理

1. 添加依赖

	.springframeork.boot
	spring-boot-starter-actuator

2. application.yaml配置
#actuator监控配置
 management:
 	endpoints:
 		eb:
   			exposure:
  			#默认值访问health,info端点  用可以包含全部端点
  			include: ''
  		#配置路径
  	base-path: /system/actuator
  	endpoint:
 	health:
   		#获得健康检查中所有指标的详细信息
   		sho-details: alays
3. 启动项目,访问

以下显示的路径,都是可以被健康检查的指标

其中谷歌浏览器显示格式为 JSON,是因为下载了 JSON-handle 插件

  • 访问路径项目路径+actuator配置路径

  • Actuator健康项

二、SpringBoot Admin(单体)

可监控的信息包含应用状态、内存、线程、堆栈等等,比较全面的监控了 Spring Boot 应用的整个生命周期。

在Spring Boot Actuator的基础上提供简洁的可视化WEB UI

SpringBoot Admin 分为服务端(spring-boot-admin-server)和客户端(spring-boot-admin-client),客户端就是指需要被监控的应用端(项目启动位置)

1. Admin Server 端
  • 新建一个项目模块,项目依赖

    
     de.codecentric
     spring-boot-admin-starter-server
     2.1.0
     
     
     .springframeork.boot
     spring-boot-starter-eb
     
    
  • application.yaml 配置文件

    # 配置tomcat访问端口
    server:
      port: 8000
    
  • 启动类

    import de.codecentric.boot.admin.server.config.EnableAdminServer;
    import .springframeork.boot.SpringApplication;
    import .springframeork.boot.autoconfigure.EnableAutoConfiguration;
    import .springframeork.context.annotation.Configuration;
    
    
    @Configuration
    @EnableAutoConfiguration
    @EnableAdminServer
    public class AdminServerApplication {
    
     public static void main(String[] args) {
      SpringApplication.run(AdminServerApplication.class, args);
     }
    }
    
  • 访问浏览器 http://localhost:8000

2. Admin Client 端
  • 在原本项目基础上,添加依赖

    
     
       de.codecentric
       spring-boot-admin-starter-client
       2.1.0
     
     
       .springframeork.boot
       spring-boot-starter-eb
     
    
    
  • 配置文件

    # 配置访问端口
    server:
      port: 20211
    spring:
      application:
     name: Admin Client
      # 配置AdminServer的地址
      boot:
     admin:
       client:
      url: http://localhost:8000
    # 打开客户端的监控
    management:
      endpoints:
     eb:
       exposure:
      include: 
    
  • 客户端启动类

    @SpringBootApplication
    public class AdminClientApplication {
      public static void main(String[] args) {
     SpringApplication.run(AdminClientApplication.class, args);
      }
    }
    
  • 先启动服务端,再启动客户端

    启动 Client 端,Admin 服务端会自动检查到客户端的变化,并展示其应用

    页面会展示被监控的服务列表,点击详项目名称会进入此应用的详细监控信息

三、OSHI

基于JNA的免费的本地操作系统和Java的硬件信息库,可以跨平台,获取监控信息简单

1. pom.xml依赖

	.github.oshi
  oshi-core
  5.6.0
 
2. 接口返回数据 3. 代码
  • Controller

    import .lzby.tqj.dto.AjaxResult;
    import .lzby.tqj.entity.Server;
    import io.sagger.;
    import .springframeork.eb.bind.annotation.;
    
    
    @CrossOrigin(origins = "", maxAge = 3600)
    @Api(tags = "系统-服务器监控")
    @RestController
    @RequestMapping("/monitor/server")
    public class ServerController {
    
     @ApiOperation(value = "获得服务器相关信息", notes = "获得服务器相关信息")
     @PostMapping(value = "/getInfo")
     public AjaxResult getInfo() thros Exception {
      Server server = ne Server();
      server.copyTo();
      return AjaxResult.suess(server);
     }
    }
    
  • entity - Server

    package .lzby.tqj.entity;
    
    import .lzby.tqj.mon.IpUtils;
    import .lzby.tqj.mon.util.Arith;
    import .lzby.tqj.entity.server.;
    import oshi.;
    
    import java..IAddress;
    
    import java.util.;
    
    
    public class Server {
     private static final int OSHI_WAIT_SECOND = 1000;
    
     // CPU相关信息
     private Cpu cpu = ne Cpu();
    
     // 內存相关信息
     private Mem mem = ne Mem();
    
     // JVM相关信息
     private Jvm jvm = ne Jvm();
    
     // 服务器相关信息
     private Sys sys = ne Sys();
    
     // 磁盘相关信息
     private List sysFiles = ne linkedList();
    
     public Cpu getCpu() {
      return cpu;
     }
    
     public void setCpu(Cpu cpu) {
      this.cpu = cpu;
     }
    
     public Mem getMem() {
      return mem;
     }
    
     public void setMem(Mem mem) {
      this.mem = mem;
     }
    
     public Jvm getJvm() {
      return jvm;
     }
    
     public void setJvm(Jvm jvm) {
      this.jvm = jvm;
     }
    
     public Sys getSys() {
      return sys;
     }
    
     public void setSys(Sys sys) {
      this.sys = sys;
     }
    
     public List getSysFiles() {
      return sysFiles;
     }
    
     public void setSysFiles(List sysFiles) {
      this.sysFiles = sysFiles;
     }
    
     public void copyTo() thros Exception {
      SystemInfo si = ne SystemInfo();
      HardareAbstractionLayer hal = si.getHardare();
      setCpuInfo(hal.getProcessor());
      setMemInfo(hal.getMemory());
      setSysInfo();
      setJvmInfo();
      setSysFiles(si.getOperatingSystem());
     }
    
     
     private void setCpuInfo(CentralProcessor processor) {
      // CPU信息
      long[] prevTicks = processor.getSystemCpuLoadTicks();
      Util.sleep(OSHI_WAIT_SECOND);
      long[] ticks = processor.getSystemCpuLoadTicks();
      long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
      long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
      long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
      long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
      long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
      long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
      long ioait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
      long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
      long totalCpu = user + nice + cSys + idle + ioait + irq + softirq + steal;
      cpu.setCpuNum(processor.getLogicalProcessorCount());
      cpu.setTotal(totalCpu);
      cpu.setSys(cSys);
      cpu.setUsed(user);
      cpu.setWait(ioait);
      cpu.setFree(idle);
     }
    
     
     private void setMemInfo(GlobalMemory memory) {
      mem.setTotal(memory.getTotal());
      mem.setUsed(memory.getTotal() - memory.getAvailable());
      mem.setFree(memory.getAvailable());
     }
    
     
     private void setSysInfo() {
      Properties props = System.getProperties();
      sys.setComputerName(getHostName());
      sys.setComputerIp(getHostIp());
      sys.setOsName(props.getProperty("os.name"));
      sys.setOsArch(props.getProperty("os.arch"));
      sys.setUserDir(props.getProperty("user.dir"));
     }
    
     
     private void setJvmInfo() thros UnknonHostException {
      Properties props = System.getProperties();
      jvm.setTotal(Runtime.getRuntime().totalMemory());
      jvm.setMax(Runtime.getRuntime().maxMemory());
      jvm.setFree(Runtime.getRuntime().freeMemory());
      jvm.setVersion(props.getProperty("java.version"));
      jvm.setHome(props.getProperty("java.home"));
     }
    
     
     private void setSysFiles(OperatingSystem os) {
      FileSystem fileSystem = os.getFileSystem();
      List fsArray = fileSystem.getFileStores();
      for (OSFileStore fs : fsArray) {
       long free = fs.getUsableSpace();
       long total = fs.getTotalSpace();
       long used = total - free;
       SysFile sysFile = ne SysFile();
       sysFile.setDirName(fs.getMount());
       sysFile.setSysTypeName(fs.getType());
       sysFile.setTypeName(fs.getName());
       sysFile.setTotal(convertFileSize(total));
       sysFile.setFree(convertFileSize(free));
       sysFile.setUsed(convertFileSize(used));
       sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
       sysFiles.add(sysFile);
      }
     }
    
     
     public String convertFileSize(long size) {
      long kb = 1024;
      long mb = kb  1024;
      long gb = mb  1024;
      if (size >= gb) {
       return String.format("%.1f GB", (float) size / gb);
      } else if (size >= mb) {
       float f = (float) size / mb;
       return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
      } else if (size >= kb) {
       float f = (float) size / kb;
       return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
      } else {
       return String.format("%d B", size);
      }
     }
     
     public static String getHostIp() {
      try {
       return IAddress.getLocalHost().getHostAddress();
      } catch (UnknonHostException e) {
      }
      return "127.0.0.1";
     }
    
     public static String getHostName() {
      try {
       return IAddress.getLocalHost().getHostName();
      } catch (UnknonHostException e) {
      }
      return "未知";
     }
    }
    
    
  • entity - Cpu

    package .lzby.tqj.entity.server;
    
    import .lzby.tqj.mon.util.Arith;
    
    
    public class Cpu
    {
     // 核心数
     private int cpuNum;
    
     // CPU总的使用率
     private double total;
    
     // CPU系统使用率
     private double sys;
    
     // CPU用户使用率
     private double used;
    
     // CPU当前等待率
     private double ait;
    
     // CPU当前空闲率
     private double free;
    
     public int getCpuNum(){
      return cpuNum;
     }
    
     public void setCpuNum(int cpuNum){
      this.cpuNum = cpuNum;
     }
    
     public double getTotal(){
      return Arith.round(Arith.mul(total, 100), 2);
     }
    
     public void setTotal(double total){
      this.total = total;
     }
    
     public double getSys(){
      return Arith.round(Arith.mul(sys / total, 100), 2);
     }
    
     public void setSys(double sys){
      this.sys = sys;
     }
    
     public double getUsed(){
      return Arith.round(Arith.mul(used / total, 100), 2);
     }
    
     public void setUsed(double used){
      this.used = used;
     }
    
     public double getWait(){
      return Arith.round(Arith.mul(ait / total, 100), 2);
     }
    
     public void setWait(double ait){
      this.ait = ait;
     }
    
     public double getFree(){
      return Arith.round(Arith.mul(free / total, 100), 2);
     }
    
     public void setFree(double free){
      this.free = free;
     }
    }
    
  • entity - Mem

    package .lzby.tqj.entity.server;
    
    import .lzby.tqj.mon.util.Arith;
    
    
    public class Mem{
     // 内存总量
     private double total;
    
     // 已用内存
     private double used;
    
     // 剩余内存
     private double free;
    
     public double getTotal(){
      return Arith.div(total, (1024  1024  1024), 2);
     }
    
     public void setTotal(long total){
      this.total = total;
     }
    
     public double getUsed(){
      return Arith.div(used, (1024  1024  1024), 2);
     }
    
     public void setUsed(long used){
      this.used = used;
     }
    
     public double getFree(){
      return Arith.div(free, (1024  1024  1024), 2);
     }
    
     public void setFree(long free){
      this.free = free;
     }
    
     public double getUsage(){
      return Arith.mul(Arith.div(used, total, 4), 100);
     }
    }
    
  • entity - Jvm

    package .lzby.tqj.entity.server;
    
    import java.lang.management.ManagementFactory;
    import .lzby.tqj.mon.util.Arith;
    import .lzby.tqj.mon.util.DateUtils;
    
    
    public class Jvm{
     // 当前JVM占用的内存总数(M)
     private double total;
    
     // JVM最大可用内存总数(M)
     private double max;
    
     // JVM空闲内存(M)
     private double free;
    
     // JDK版本
     private String version;
    
     // JDK路径
     private String home;
    
     public double getTotal(){
      return Arith.div(total, (1024  1024), 2);
     }
    
     public void setTotal(double total){
      this.total = total;
     }
    
     public double getMax(){
      return Arith.div(max, (1024  1024), 2);
     }
    
     public void setMax(double max){
      this.max = max;
     }
    
     public double getFree(){
      return Arith.div(free, (1024  1024), 2);
     }
    
     public void setFree(double free){
      this.free = free;
     }
    
     public double getUsed(){
      return Arith.div(total - free, (1024  1024), 2);
     }
    
     public double getUsage(){
      return Arith.mul(Arith.div(total - free, total, 4), 100);
     }
    
     // 获取JDK名称
     public String getName(){
      return ManagementFactory.getRuntimeMXBean().getVmName();
     }
    
     public String getVersion(){
      return version;
     }
    
     public void setVersion(String version){
      this.version = version;
     }
    
     public String getHome(){
      return home;
     }
    
     public void setHome(String home){
      this.home = home;
     }
    
     // JDK启动时间
     public String getStartTime(){
      return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
     }
    
     // JDK运行时间
     public String getRunTime()
     {
      return DateUtils.getDatePoor(DateUtils.getNoDate(), DateUtils.getServerStartDate());
     }
    }
    
  • entity - Jvm

    package .lzby.tqj.entity.server;
    
    import lombok.Data;
    
    
    @Data
    public class Sys{
     
     // 服务器名称
     private String puterName;
    
     // 服务器Ip
     private String puterIp;
    
     // 项目路径
     private String userDir;
    
     // 操作系统
     private String osName;
    
     // 系统架构
     private String osArch;
    }
    
  • 工具类 Arith

    package .lzby.tqj.mon.util;
    
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    
    
    public class Arith{
    
     
     private static final int DEF_DIV_SCALE = 10;
    
     
     private Arith(){}
    
     
     public static double add(double v1, double v2){
      BigDecimal b1 = ne BigDecimal(Double.toString(v1));
      BigDecimal b2 = ne BigDecimal(Double.toString(v2));
      return b1.add(b2).doublevalue();
     }
    
     
     public static double mul(double v1, double v2){
      BigDecimal b1 = ne BigDecimal(Double.toString(v1));
      BigDecimal b2 = ne BigDecimal(Double.toString(v2));
      return b1.multiply(b2).doublevalue();
     }
    
     
     public static double div(double v1, double v2, int scale){
      if (scale < 0){
       thro ne IllegalArgumentException(
         "The scale must be a positive integer or zero");
      }
      BigDecimal b1 = ne BigDecimal(Double.toString(v1));
      BigDecimal b2 = ne BigDecimal(Double.toString(v2));
      if (b1.pareTo(BigDecimal.ZERO) == 0){
       return BigDecimal.ZERO.doublevalue();
      }
      return b1.divide(b2, scale, RoundingMode.HALF_UP).doublevalue();
     }
    
     
     public static double round(double v, int scale){
      if (scale < 0){
       thro ne IllegalArgumentException(
         "The scale must be a positive integer or zero");
      }
      BigDecimal b = ne BigDecimal(Double.toString(v));
      BigDecimal one = ne BigDecimal("1");
      return b.divide(one, scale, RoundingMode.HALF_UP).doublevalue();
     }
    }
    
    

Copyright © 2016-2025 www.caominkang.com 曹敏电脑维修网 版权所有 Power by