prometheus 配置服务器监控、服务监控、容器中服务监控与告警

news2024/9/30 1:32:17

       最近公司有几个服务遇到了瓶颈,也就是数据量增加了,没有人发现,这不是缺少一个监控服务和告警的系统吗?  

      主要需求是监控每个服务,顺带监控一下服务器和一些中间件,这里采集的2种,zabbix和prometheus,由于我们要监控的是Docker容器中的服务,最终选择prometheus。

如下:

一 实现功能

  1. 服务宕机,不能提供服务,飞书收到告警信息。
  2. 容器中服务占用分配内存达到50, 飞书收到预警信息。
  3. 容器中服务中JVM堆内存占用达到80, 飞书收到预警信息。
  4. 服务发生OOM后,服务可以立刻重启。

 二:流程图

 三 步骤

确定要监控的docker服务, 这里以公司的A服务为例子

  1. 查看服务的Dockerfile 和run.sh   

Dockerfile是构建docker镜像,run.sh是启动服务用的

 1.1 Dockerfile中java执行命令添加:

"-XX:+HeapDumpOnOutOfMemoryError","-XX:HeapDumpPath=/temp/dump","-XX:+ExitOnOutOfMemoryError","-XX:MaxRAMPercentage=75.0"

-XX:+HeapDumpOnOutOfMemoryError:参数表示当JVM发生OOM时,自动生成DUMP文件

-XX:HeapDumpPath=/temp/dump:生成dump目录文件的位置

-XX:+ExitOnOutOfMemoryError:JVM在第一次出现内存不足错误时退出,启动JVM实例

-XX:MaxRAMPercentage=75.0: 这为JVM定义了75%的总内存限制

查看服务目前容器大小,和占用内存大小,保证占用内存稳定在30%一下。

docker stats dcda4228b794

 这边找了一个47%的,只给了1G的容器大小。需求中超过50%就会告警。

如果超过50%,需要在启动容器的run.sh命令中提升初始容器大小

修改--memory 1024m \   --memory-swap 1024m \的值,是容器的内存大小

以上是容器要做的一些调整,也是自己定义的规则。

2. Idea中找到A应用,修改POM和 application.properties文件

application.properties中添加

management.endpoint.health.show-details=always
management.endpoints.web.exposure.include=*

这边要注意,如果你是yml文件 management.endpoints.web.exposure.include=*,

这个 * 一定要加 ''单引号,*在yml文件中是通配符。

POM中添加,目的是当前服务可以提供一些监控指标

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

 注意,如果你的服务属于对外接口访问服务,有Shiro拦截的话要配置

filterChainDefinitionMap.put("/actuator/prometheus", "anon");

至此完成代码的整改,可以提交代码,部署服务。

确定服务正常启动:输入docker ps -a  (不加-a就看正常运行的服务,-a是看所有的服务,包括停止的)

 去服务器厂商放开当前服务对外的端口号,主要是对指定监控的服务器放开,不是所有

环境地址访问  http://ip:port/actuator/prometheus

看到如下,就是提供的指标数据

 3 docker容器监控服务

部署prometheus,alertmanager,garfana, 还有一个推消息给飞书的服务, 这个大家如果想找到怎么部署,可以留言,我整理一下,写出来。不过后面有时间我也会更新这边部署监控文章的。

1. cadvisor 是容器内个服务的监控指标提取

2. prometheus-webhook-feishu 是网上找的一个开源的飞书通知服务

3.alertmanager是告警管理 --通知2下发告警的

4.grafana是可视化大屏,对prometheus采集的数据可视化展示

5.node-exporter 是服务器监控,提取服务器的指标数据

6.prometheus 是核心的监控服务

4. 配置prometheus

进入prometheus

 看到这几个文件夹/文件,其中主要配置实例在prometheus.yml中,rules文件下是配置告警规则的。

进入prometheus.yml仿照- job_name: 自己创建一个

- job_name: "A"    # 监控的job名称

    metrics_path: '/actuator/prometheus'   # 监控的指标路径

    static_configs:

      - targets: ['ip:port']    #监控的服务器和端口端口已经开放

        labels:

          serviceId: A-snapshot   #服务id告警展示

          serviceName: A-web  #服务名称   告警展示

重启prometheus

docker restart prometheus

访问http://ip:9090/查看配置的任务,如下up状态代表服务正常启动,配置任务成功。

 rules下有配置服务器/服务的告警规则

1. 服务器内存使用超过98%告警规则

  (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes )) / node_memory_MemTotal_bytes * 100 > 98

 (node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes * 100 > 95

会对配置在prometheus中没有job都做监控,up==0标识改服务宕机,提示。

可以做验证

 docker stop A服务容器id

 

飞书收到这个通知,如何配置 prometheus-alertmanager-feishu的流程后续会同步上

4.配置其他告警规则 这里配置容器内存超过50提示,和服务jvm中堆占用80提示

配置路径/minitor/prometheus/rules

可以自己重新定义一个yml ,下面yml下面所有规则都会被prometheus识别,一般按照项目建一个文件

容器内存超过50


groups:
# 组名。报警规则组名称
- name:  A服务内存预警
  rules:
  - alert:  a服务内存使用率预警
  # expr:基于PromQL表达式告警触发条件,用于计算是否有时间序列满足该条件。
    expr: container_memory_usage_bytes{image="a:latest"}/container_spec_memory_limit_bytes{image="a:latest"} * 100 > 50
  # for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending。
    for: 20s # for语句会使 Prometheus 服务等待指定的时间, 然后执行查询表达式。(for 表示告警持续的时长,若持续时长小于该时间就不发给alertmanager了,大于
该时间再发。for的值不要小于prometheus中的scrape_interval,例如scrape_interval为30s,for为15s,如果触发告警规则,则再经过for时长后也一定会告警,这是因为>最新的度量指标还没有拉取,在15s时仍会用原来值进行计算。另外,要注意的是只有在第一次触发告警时才会等待(for)时长。)
  # labels:自定义标签,允许用户指定要附加到告警上的一组附加标签。
    labels:
    # severity: 指定告警级别。有三种等级,分别为 warning, critical 和 emergency 。严重等级依次递增。
      severity: critical
  # annotations: 附加信息,比如用于描述告警详细信息的文字等,annotations的内容在告警产生时会一同作为参数发送到Alertmanager。
    annotations:
      title: "a服务内存使用率预警"
      serviceName: "{{ $labels.serviceName }}"
      instance: "{{ $labels.instance }}"
      value: "{{ $value }}"
      btn: "点击查看详情 :玫瑰:"
      link: "http://xxxxxxxxx:9090/targets"
      template: "**${serviceName}**(${instance})正式服务内存使用率已经超过阈值 **50%**, 请及时处理!\n当前值: ${value}%"

expr:container_memory_usage_bytes{image="a:latest"}/container_spec_memory_limit_bytes{image="a:latest"} * 100 > 50
这个可以在之前prometheus查看

服务jvm中堆占用80提示


- name: A服务堆内存超高预警
  rules:
  - alert: A服务堆内存使用率超高预警
    expr: sum(jvm_memory_used_bytes{serviceId="a", area="heap"})*100/sum(jvm_memory_max_bytes{serviceId="a", area="heap"}) > 80
    for: 20s
    labels:
       severity: red
    annotations:
      title: "a服务堆内存使用率超高预警"
      serviceName: "{{ $labels.serviceName }}"
      instance: "{{ $labels.instance }}"
      value: "{{ $value }}"
      btn: "点击查看详情 :玫瑰:"
      link: "http://xxxxxxxx:9090/targets"
      template: "**${serviceName}**(${instance})正式环境服务内存使用率已经超过阈值 **80%**, 请及时处理!\n当前值: ${value}%"

 expr: sum(jvm_memory_used_bytes{serviceId="job中配置的", area="heap"})*100/sum(jvm_memory_max_bytes{serviceId="job中配置的", area="heap"}) > 80

 

 重启prometheus

5 验证容器内存超过50  堆内存超80  和出现OOM后容器自动重启服务

 在服务中加一个测试oom的接口, 正式发布后,这个接口要去掉

如下: 会不断的生成不回收的对象 /dev/d

package xxx;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 */
@Slf4j
@RestController
@RequestMapping("dev")
public class Controller {


    @RequestMapping("/a")
    public Integer message() {
        log.info(">>>>info");
        log.debug(">>>>>Debug");
        return Runtime.getRuntime().availableProcessors();
    }

    @RequestMapping("/d")
    public String messaged(HttpServletRequest request) throws InterruptedException {
        log.info(">>>>info");
        log.debug(">>>>>Debug");
        List<Object> list = new ArrayList<>();
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<Object> list2 = new ArrayList<>();
                int initSize =  1024 * 1024 * 300;
                Map<String, Object> map = new HashMap<>();
                int i= 0;
                while(true) {
                    try{
                        Thread.sleep(5000);
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                    //每次添加50M
                    int userMemory = 1024*1024*10;
                    i++;
                    map.put("userMemory" + i, new byte[userMemory]);
                    list.add(map);
                    list2.add(map);
                }
            }
        }).start();
        return "OK";
    }
}

这里对A服务运行dev/d接口

先看dev/a 是看运行的cpu个数,验证服务是否启动

这时候别着急让服务OOM

先看cAdvisor,容器监控都靠他,监控别的服务器容器也要在对应服务器上安装。

环境运行: http://ip:19190/

点击Docker Containers可以看具体容器的信息,找到你要配置的容器A

里面包括很多参数指标信息,这里先看容器内存

 

 和docker stats运行的值基本一致

Jvm堆内存使用占比,我们可以根据cAdvisor提供的

jvm_memory_used_bytes

jvm_memory_max_bytes

执行接口,查看对应数据,验证告警信息。

 等会我们执行增加jvm堆内存的接口,要看容器的内存使用,和jvm中堆占比都上升,知道堆内存占比100%发生OOM后,容器重启服务,过程中,会提示容器内存使用超过50%,堆内存使用超过80%

1. 系统OOM 产生dump文件 之前第一步有配置

2. 系统OOM 会立刻重启服务,保证不宕机,服务可用

3. 容器内存超50% 告警

4. 堆内存超80% 告警

第一个:

在docker下dump/temp发现 java_pid6.hprof 文件--后面讲

第二个 服务立刻重启,并且输入dev/a  还是可以访问的

第三个 收到告警

这个过程,百分比是慢慢上升的可以通过docker stats/cadvisor看数据

  • 继续监控

 此时堆内存已经达到91 > 80

 容器内存也快达到,瓶颈

 

  • 继续监控,突然会服务重新,出现OOM

也可以docker logs -f xxx查看日志,此时对象都释放掉了

又回到服务初始容器内存占比和jvm堆使用占比

至此,完成了服务宕机告警,容器内存超50%告警,堆内存超80%告警,服务出现OOM后服务重启。

6 可视化监控的页面grafana

可以通过看大屏数据,感觉还挺牛的,可以自定义。

http://xxxxx:3000/    grafana可视化监控,是对prometheus采集的数据做大屏展示

如:展示刚刚容器中jvm的一些指标信息  配置模板id:4701 用过grafana你就知道了。相当于一个模版id

 展示当前服务器中所有容器的cpu,内存,硬盘等使用情况

模板id: 116000 是查看当前容器中各服务,cpu,内存使用情况。

 也可以对整个服务器做监控展示    模板id:8919

grafana的更多常用模板地址:Dashboards | Grafana Labs 

目前监控的实现方案如上,有好的优化方案和新的监控点,告警点互相讨论。

上面代码出现OOM,简单排查过程

主要是分析dump文件

通过写的代码,看到开启一个线程,不停的给ArrayList插入一个value是10M的Map

在配置java启动中,我们把oom自动生成的dump文件拿出来

进到容器中把文件cp到宿主机

 分析工具:MemoryAnalyzer  导入文件

1 进入Leak Suspects  2进入Dominator Tree

进入Leak Suspects 点击detail  发现出现一堆HashMap没有回收,这和我们的代码问题一致

 

 进入 Dominator Tree查看

发现有很多的HashMap key 是递增的,value是一个10M的Byte[]

代码都是自己写的。哈哈。

 定位代码:

服务地址:

Promethues:   http://xxxx:9090

Grafana: http://xxxx:3000

Alertmanager: http://xxxx:19093

cAdvisor的所有容器监控 http://xxxxx:19190/containers/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/398593.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka 消费者组

Kafka 消费者组Consumer数位移重平衡消费者组 (Consumer Group) : 可扩展且容错性的消费者机制 一个组内可能有多个消费者 (Consumer Instance) : 共享一个公共 ID (Group ID)组内的所有消费者协调消费订阅主题 (Subscribed Topics) 的所有分区 (Partition)每个分区只能由同个…

【1】熟悉刷题平台操作

TestBench使用 与quartus中testbench的写法有些许。或者说这是平台特有的特性&#xff01;&#xff01; 1 平台使用谨记 &#xff08;1&#xff09;必须删除&#xff1a;若设计为组合逻辑&#xff0c;需将自动生成的clk删除 若不删除&#xff0c;会提示运行超时错误。 &#…

git推送指定的提交到远程分支详细方法

默认情况下&#xff0c;git push会推送暂存区所有提交&#xff08;也即HEAD及其之前的提交&#xff09;到远程库&#xff0c;实际开发中可能因为功能没有开发完成&#xff0c;但是又必须提交部分修改好的代码就需要用到推送指定commit到远程分支。第一种方式&#xff1a;即符合…

CSS流动布局-页面自适应

项目中经常会碰到页面自适应的问题&#xff0c;例如&#xff1a;商城的列表展示、分类列表展示等页面&#xff0c;如下&#xff1a; 该页面会随着页面的放大缩小而随之发生变化&#xff0c;这种自适应的页面布局在大屏幕、小屏幕、不同的浏览器设备上都应该呈现出与设计匹配的…

【STM32MP157应用编程】4.串口接收、发送数据

目录 串口文件 指令操作串口 程序操作串口 程序说明 程序代码 4_ChuanKou_2.c 启动交叉编译工具 编译 拷贝到开发板 测试 串口文件 在/dev目录下&#xff0c;存放了串口的文件。 文件名对应的串口ttySTM0CH340ttySTM1com2&#xff08;公头&#xff09;ttySTM2com1&a…

java版云HIS系统源码 微服务架构支持VUE

云his系统源码 一个好的HIS系统&#xff0c;要具有开放性&#xff0c;便于扩展升级&#xff0c;增加新的功能模块&#xff0c;支撑好医院的业务的拓展&#xff0c;而且可以反过来给医院赋能&#xff0c;最终向更多的患者提供更好地服务。 私信了解更多&#xff01; 本套基于…

【C语言】结构体和共用体

目录一、结构体&#xff08;一&#xff09;结构体声明&#xff08;二&#xff09;结构体变量定义&#xff08;三&#xff09;结构体变量的初始化&#xff08;四&#xff09;结构体的引用&#xff08;五&#xff09;结构体数组二、共用体&#xff08;一&#xff09;共用体定义&a…

全球商城库存系统架构设计与实践

业务背景 商城原库存系统耦合在商品系统&#xff0c;考虑到相关业务逻辑复杂度越来越高&#xff0c;库存做了服务拆分&#xff0c;在可售库存管理的基础上新增了实物库存管理、秒杀库存、物流时效 、发货限制、分仓管理等功能&#xff0c;满足了商城库存相关业务需求。 系统架构…

GitLab 存储型XSS漏洞 (CVE-2023-0050)

漏洞描述 GitLab 是由GitLab公司开发的、基于Git的集成软件开发平台。kroki是一款集成在GitLab的基于文本的图表描述自动转为图片的开源工具&#xff0c;在GitLab 13.7引入。 由于Kroki中lib/banzai/filter/kroki_filter.rb对接收的image_src过滤不严&#xff0c;具有AsciiDo…

SpringBoot 整合 clickhouse和mysql 手把手教程全网最详细

最近做一个项目 需要 整合mysql clickhouse 多数据源 后台用的是ruoyi框架 1. 首先pom引入相关依赖 <!--JDBC-clickhouse数据库--><dependency><groupId>com.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version&…

Homekit智能家居产品---智能吸顶灯

买灯要看什么因素 好灯具的灯光可以说是家居的“魔术师”&#xff0c;除了实用的照明功能外&#xff0c;对细节的把控也非常到位。那么该如何选到一款各方面合适的灯呢&#xff1f; 照度 可以简单理解为清晰度&#xff0c;复杂点套公式来说照度光通量&#xff08;亮度&#x…

5款小巧好用的电脑软件,让你的工作生活更加高效!

不得不说良心好软件让大家好评连连&#xff0c;爱不释手&#xff0c;不像某些软件自带广告弹窗。这期就由我给大家安利几款电脑中的得力助手&#xff0c;看看你都用过几个&#xff1f; 1.桌面管理神器——Coodesker Coodesker是一款免费小巧、无广告&#xff0c;功能简单的桌…

【Redis】哨兵机制(三)

目录 3.Redis哨兵 3.1.哨兵原理 3.1.1.集群结构和作用 3.1.2.集群监控原理 3.1.3.集群故障恢复原理 3.1.4.小结 3.2.搭建哨兵集群 3.3.RedisTemplate 3.3.1.导入Demo工程 3.3.2.引入依赖 3.3.3.配置Redis地址 3.3.4.配置读写分离 3.Redis哨兵 Redis提供了哨兵&am…

Spring Cloud Gateway学习

文章大纲 为什么需要网关&#xff1f; 传统的单体架构只有一个服务开放给客户端调用&#xff0c;但是在微服务架构体系中是将一个系统拆分成多个微服务&#xff0c;那么作为客户端如何去调用这些微服务呢&#xff1f;如果没有网关的存在&#xff0c;就只能在本地记录每个微服务…

彻底关闭Windows10更新!!

以下四个步骤都需要执行。 一、禁用Windows Update服务 1、同时按下键盘 Win R&#xff0c;然后输入 services.msc &#xff0c;点击确定。 2、找到 Windows Update 这一项&#xff0c;并双击打开。 3、双击打开它&#xff0c;点击 停止&#xff0c;把启动类型选为 禁用&…

SpringBoot+@Async注解-异步调用

编程开发里&#xff0c;使用java异步执行方法可以让程序同时处理多个请求业务&#xff0c;提升吞吐量来缩短业务的执行时间&#xff0c;在springboot的程序应用中&#xff0c;提供了Async注解来实现异步执行方法。在业务开发中&#xff0c;有些时候是不需要立即返回业务的处理结…

前端代码质量-圈复杂度原理和实践

1. 导读 你们是否也有过下面的想法&#xff1f; 重构一个项目还不如新开发一个项目…这代码是谁写的&#xff0c;我真想… 你们的项目中是否也存在下面的问题&#xff1f; 单个项目也越来越庞大&#xff0c;团队成员代码风格不一致&#xff0c;无法对整体的代码质量做全面的…

【LeetCode】剑指 Offer 25. 合并两个排序的链表 p145 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/ 1. 题目介绍&#xff08;25. 合并两个排序的链表&#xff09; 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 【测试用例】&#xf…

软件测试分类知识分享,第三方软件测试机构收费贵不贵?

软件测试可以很好的检验软件产品的质量以及规避产品上线之后可能会发生的错误&#xff0c;随着技术的发展&#xff0c;软件测试已经是一个完整且体系庞大的测试活动&#xff0c;不同的测试领域有着不同的测试方法、技术与名称&#xff0c;那么具体有哪些分类呢? 一、软件测试…

centos7部署KVM虚拟化

目录 centos7部署KVM虚拟化平台 1、新建一台虚拟机 2、系统内的操作 1、修改主机名 2、挂载镜像光盘 3、ssh优化 4、设置本地yum仓库 5、关闭防火墙&#xff0c;selinux 3、安装KVM 4、设置KVM网络 5、KVM部署与管理 6、使用虚拟系统管理器管理虚拟机 创建存储池 …