服务器监控功能(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. 添加依赖
<!-- 引入Actuator监控依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. application.yaml配置
#actuator监控配置management:endpoints:web:exposure:#默认值访问health,info端点  用*可以包含全部端点include: '*'#配置路径base-path: /system/actuatorendpoint:health:#获得健康检查中所有指标的详细信息show-details: always
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 端
  • 新建一个项目模块,项目依赖

    <dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
    
  • application.yaml 配置文件

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

    import de.codecentric.boot.admin.server.config.EnableAdminServer;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.Configuration;/*** Springboot admin 服务器监控 -- 服务端** @Author: changge* @date 2021/8/25 17:43* @return null**/
    @Configuration
    @EnableAutoConfiguration
    @EnableAdminServer
    public class AdminServerApplication {public static void main(String[] args) {SpringApplication.run(AdminServerApplication.class, args);}
    }
    
  • 访问浏览器 http://localhost:8000

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

    <dependencies><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
    </dependencies>
    
  • 配置文件

    # 配置访问端口
    server:port: 20211
    spring:application:name: Admin Client# 配置AdminServer的地址boot:admin:client:url: http://localhost:8000
    # 打开客户端的监控
    management:endpoints:web: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依赖
<!-- 获取系统信息 -->
<dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId><version>5.6.0</version></dependency>
2. 接口返回数据

3. 代码
  • Controller

    import com.lzby.tqj.dto.AjaxResult;
    import com.lzby.tqj.entity.Server;
    import io.swagger.*;
    import org.springframework.web.bind.annotation.*;/*** 服务器监控**/
    @CrossOrigin(origins = "*", maxAge = 3600)
    @Api(tags = "系统-服务器监控")
    @RestController
    @RequestMapping("/monitor/server")
    public class ServerController {@ApiOperation(value = "获得服务器相关信息", notes = "获得服务器相关信息")@PostMapping(value = "/getInfo")public AjaxResult getInfo() throws Exception {Server server = new Server();server.copyTo();return AjaxResult.success(server);}
    }
    
  • entity - Server

    package com.lzby.tqj.entity;import com.lzby.tqj.common.IpUtils;
    import com.lzby.tqj.common.util.Arith;
    import com.lzby.tqj.entity.server.*;
    import oshi.*;import java.net.InetAddress;import java.util.*;/*** 服务器相关信息**/
    public class Server {private static final int OSHI_WAIT_SECOND = 1000;// CPU相关信息private Cpu cpu = new Cpu();// 內存相关信息private Mem mem = new Mem();// JVM相关信息private Jvm jvm = new Jvm();// 服务器相关信息private Sys sys = new Sys();// 磁盘相关信息private List<SysFile> sysFiles = new LinkedList<SysFile>();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<SysFile> getSysFiles() {return sysFiles;}public void setSysFiles(List<SysFile> sysFiles) {this.sysFiles = sysFiles;}public void copyTo() throws Exception {SystemInfo si = new SystemInfo();HardwareAbstractionLayer hal = si.getHardware();setCpuInfo(hal.getProcessor());setMemInfo(hal.getMemory());setSysInfo();setJvmInfo();setSysFiles(si.getOperatingSystem());}/*** 设置CPU信息*/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 iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;cpu.setCpuNum(processor.getLogicalProcessorCount());cpu.setTotal(totalCpu);cpu.setSys(cSys);cpu.setUsed(user);cpu.setWait(iowait);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"));}/*** 设置Java虚拟机*/private void setJvmInfo() throws UnknownHostException {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<OSFileStore> fsArray = fileSystem.getFileStores();for (OSFileStore fs : fsArray) {long free = fs.getUsableSpace();long total = fs.getTotalSpace();long used = total - free;SysFile sysFile = new 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);}}/*** 字节转换** @param size 字节大小* @return 转换后值*/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 InetAddress.getLocalHost().getHostAddress();} catch (UnknownHostException e) {}return "127.0.0.1";}public static String getHostName() {try {return InetAddress.getLocalHost().getHostName();} catch (UnknownHostException e) {}return "未知";}
    }
  • entity - Cpu

    package com.lzby.tqj.entity.server;import com.lzby.tqj.common.util.Arith;/*** CPU相关信息*/
    public class Cpu
    {// 核心数private int cpuNum;// CPU总的使用率private double total;// CPU系统使用率private double sys;// CPU用户使用率private double used;// CPU当前等待率private double wait;// 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(wait / total, 100), 2);}public void setWait(double wait){this.wait = wait;}public double getFree(){return Arith.round(Arith.mul(free / total, 100), 2);}public void setFree(double free){this.free = free;}
    }
    
  • entity - Mem

    package com.lzby.tqj.entity.server;import com.lzby.tqj.common.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 com.lzby.tqj.entity.server;import java.lang.management.ManagementFactory;
    import com.lzby.tqj.common.util.Arith;
    import com.lzby.tqj.common.util.DateUtils;/*** JVM相关信息**/
    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.getNowDate(), DateUtils.getServerStartDate());}
    }
    
  • entity - Jvm

    package com.lzby.tqj.entity.server;import lombok.Data;/*** 系统相关信息*/
    @Data
    public class Sys{// 服务器名称private String computerName;// 服务器Ipprivate String computerIp;// 项目路径private String userDir;// 操作系统private String osName;// 系统架构private String osArch;
    }
    
  • 工具类 Arith

    package com.lzby.tqj.common.util;import java.math.BigDecimal;
    import java.math.RoundingMode;/*** 精确的浮点数运算**/
    public class Arith{/** 默认除法运算精度 */private static final int DEF_DIV_SCALE = 10;/** 这个类不能实例化 */private Arith(){}/*** 提供精确的加法运算。* @param v1 被加数* @param v2 加数* @return 两个参数的和*/public static double add(double v1, double v2){BigDecimal b1 = new BigDecimal(Double.toString(v1));BigDecimal b2 = new BigDecimal(Double.toString(v2));return b1.add(b2).doubleValue();}/*** 提供精确的乘法运算。* @param v1 被乘数* @param v2 乘数* @return 两个参数的积*/public static double mul(double v1, double v2){BigDecimal b1 = new BigDecimal(Double.toString(v1));BigDecimal b2 = new BigDecimal(Double.toString(v2));return b1.multiply(b2).doubleValue();}/*** 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指* 定精度,以后的数字四舍五入。* @param v1 被除数* @param v2 除数* @param scale 表示表示需要精确到小数点以后几位。* @return 两个参数的商*/public static double div(double v1, double v2, int scale){if (scale < 0){throw new IllegalArgumentException("The scale must be a positive integer or zero");}BigDecimal b1 = new BigDecimal(Double.toString(v1));BigDecimal b2 = new BigDecimal(Double.toString(v2));if (b1.compareTo(BigDecimal.ZERO) == 0){return BigDecimal.ZERO.doubleValue();}return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();}/*** 提供精确的小数位四舍五入处理。* @param v 需要四舍五入的数字* @param scale 小数点后保留几位* @return 四舍五入后的结果*/public static double round(double v, int scale){if (scale < 0){throw new IllegalArgumentException("The scale must be a positive integer or zero");}BigDecimal b = new BigDecimal(Double.toString(v));BigDecimal one = new BigDecimal("1");return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();}
    }

服务器监控功能(3种方案)相关推荐

  1. 在树莓派上实现usb摄像头监控的几种方案

    在树莓派上使用usb摄像头时,由于无法直接通过raspivid工具直接采集视频流,因此很多适用于树莓派专用摄像头的监控方案难以实现. 使用环境: 树莓派3B+uvc摄像头(即常见的即插即用usb摄像头 ...

  2. 性能服务器闹钟功能,一种服务器及其闹钟实现方法

    1. 一种服务器的闹钟实现方法,其特征在于,所述服务器接入到网络上,所述服务器为 智能路由器或家庭云服务器,所述方法包括: 对连接到所述网络上的设备进行判断,将具有声音播放模块以及接入到所述网络的设 ...

  3. 高性能游戏服务器架构设计,一种高性能大型多人在线角色扮演游戏服务器架构设计.doc...

    一种高性能大型多人在线角色扮演游戏服务器架构设计 一种高性能大型多人在线角色扮演游戏服务器架构设计摘要:大型多人在线角色扮演游戏(Massively Multiplayer Online Role P ...

  4. DHCP 服务器监控

    网络中使用了数千个 IP 地址,当今大多数组织中的 IP 地址都由 DHCP 服务器提供服务.必须发现可用的 IP 地址.了解如何预配 IP 并了解 IP 池利用率.使用 DHCP 服务器进行 IP ...

  5. 体验监控宝免费网站服务器监控服务 附注册账户及网站监控部署方法

    无论是我们个人网站还是公司企业专业运维人员,对于公司服务器.网站等项目肯定不能全天24小时的在线人工监控和管理,尤其是在众多项目部署的时候,我们根本顾及不过来所有项目网站.服务器的稳定性.比如经常有遇 ...

  6. [shell] IT运维之Linux服务器监控方案

    随着Linux应用日益广泛,绝大部分的网络服务器都使用Linux操作系统.为了全面掌握网络服务器的运行状况和趋势,需要对服务器进行全面的监控. 利用Linux发行版搭建一个网络服务器可能对于许多人都是 ...

  7. 新一代服务器监控系统,NVR成为新一代的视频监控存储标准方案

    [导读] NVR作为视频监控行业的新标准,在不久的将来会替代服务器加磁盘阵列的监控存储构架,成为新一代的视频监控存储标准方案. 视频监控存储系统发展到现在,经过了三个时代:模拟时代.DVR时代,全数字 ...

  8. COS云存储有哪些优势?基于EasyCVR平台的两种监控视频数据存储方案

    随着物联网.AI.云计算.大数据等新兴技术的发展.海量设备的接入.视频质量的不断提升,监控视频存储也面临着巨大的挑战.当前用户对视频监控数据的存储问题,主要考虑到以下三个因素: 1)数据的安全性和稳定 ...

  9. 监控系统几种常见的光端机传输方案拓扑图

    近几年随着模拟摄像机被网络摄像机以及高清同轴摄像机取代,在光纤传输层,之前使用量比较大的视频光端机也逐渐被光纤收发器.POE交换机.网络交换机等网络光通信设备取代掉.目前市场上音频.数据.开关量.电话 ...

最新文章

  1. python条形图数据标签_python – Plotly中用于条形图的单独标记条形图
  2. opencv+python读写视频流
  3. Box-Cox(python实现)
  4. 医疗影像网络PACS系统方案
  5. 数据运营者的福音:海量数据处理利器Greenplum
  6. 项目中使用RDLC报表
  7. 如何在php7.2/php7.3中安装mcrypt扩展?
  8. 其中一个页签慢_VBA实战技巧15:创建索引页
  9. python常用文本处理功能
  10. 如何检查对象是否为数组?
  11. struts使用拦截器注解
  12. LoginActivity实现
  13. 电脑报制作黑客入门新手特训第1版
  14. 『软件工程8』软件项目进度安排与跟踪,一招学会计算关键路径
  15. OSM数据下载及两种格式转换方法(shp等格式)
  16. Error: ADB exited with exit code 1 Performing Streamed Install adb: failed to install D:\svn\app\sm
  17. 以XML数据源为例的一个数据结构化方法
  18. 苹果自带输入法怎么换行_Iphone手机原生输入法的5个技巧,学会了,才知道这么牛...
  19. Webstorm2016安装激活
  20. CodeForces 891 E.Lust(生成函数)

热门文章

  1. 上周五NYMEX原油期货0810合约下跌6.59美元/桶,国际油价创17年来最大单日跌幅
  2. pytorch yolov5的输入图像尺寸为指定尺寸
  3. RabbitMQ死信队列应用
  4. 【订单页面】测试用例设计
  5. 开放算力,云启未来,与龙蜥一起开启 2022 云栖大会之旅
  6. 手把手教你制作自己的ttylinux
  7. rsync+stunnel部署安装
  8. 2022年山西省安全保护服务人员(初级保安员)考试练习题及答案
  9. 计算机专业教育与创新创业,计算机专业创新创业教育模式的发展
  10. Android:安卓学习笔记之Bitmap的简单理解和使用