Prometheus + Grafana 监控,验证 Hystrix 超时熔断

前言

很多伙伴在面试的时候,都可能会被问到;你的应用接口响应时间多少,Tomcat 配置了多少连接数,如果接口超时了怎么办,会不会把服务拖垮。那会不会呢,其实会的,对于一些接口不稳定容易超时但又不熔断的接口,在用户大量请求的情况下,是很容易把Tomcat连接数打满,直至拖垮整个服务,让服务的任何接口都没有响应。
你是怎么挂的?

Tomcat 可分配的连接数就像厕所的坑位,一堆用户来上大号。本来4个坑位也够用了,因为用户来了也可以快速释放请求,不会长时间占用。但突然有这么一天,用户都拉肚子,一个进去就1个小时候,其余人都排队。最后给压垮了!

那是不是,增加了连接数(WC 更多的坑位就好了呢),其实也好不哪去,你总不能给所有的用户都建一个坑位,而且坑位越多,距离也越长了,这就会涉及到线程的切换,也是不小的资源消耗。

所以,为了保护我方Tomcat(WC 坑位),则需要快速熔断,而不是让它一直占用着链接不释放。

工程环境配置

做一个 SpringBoot 工程测试案例,并配合添加 Hystrix 熔断组件,以及使用 Grafana 监控来观察简单压测时连接数的消耗和接口性能的反馈。

jdk 1.8、Maven 3.6.x、Docker 环境
配置修改

首先,你需要打开 prometheus.yml 修改监控采集应用的IP地址。这个配置还可以监控例如 MySQL 和其他应用。
安装监控

yaml 复制代码
version: '3'
# 执行脚本;docker-compose -f docker-compose.yml up -d
# 拷贝配置;docker container cp grafana:/etc/grafana/ ./docs/dev-ops/
services:
  # 数据采集
  prometheus:
    image: bitnami/prometheus:2.47.2
    container_name: prometheus
    restart: always
    ports:
      - 9090:9090
    volumes:
      - ./etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
  # 监控界面
  grafana:
    image: grafana/grafana:10.2.0
    container_name: grafana
    restart: always
    ports:
      - 4000:4000
    depends_on:
      - prometheus
    volumes:
      - ./etc/grafana:/etc/grafana

这是 docker compose 执行脚本,如果你本地已经安装了 Docker 可以直接执行 安装即可。

注意;如果你是生产使用,则需要修改 etc/grafana/grafana.ini 中 datasources 为 mysql 这样在后面迁移的时候也会非常容易。

监控配置

安装完监控环境以后,可以先打开 Grafana 地址:http://127.0.0.1:4000 (opens new window)- admin/admin


测试应用说明

xml 复制代码
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.18</version>
</dependency>

这个熔断的组件,不需要引入 SpringCloud 一堆的东西,使用起来更加容易。

java 复制代码
@Configuration
public class HystrixConfig {

    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }

}

引入 POM 后,添加 HystrixConfig 熔断配置。

接口配置

提供了2个接口,一个普通的查询数据接口,一个是 OpenAi 中服务的给前端异步响应结果的接口。尤其是 OpenAi 异步接口,我们在实际使用的时候,也总会有超时熔断。

普通接口

java 复制代码
/**
 * curl http://localhost:8091/api/hystrix/query_order_info
 */
@HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "50")
}, fallbackMethod = "queryOrderInfo_error"
)
@RequestMapping(value = "query_order_info", method = RequestMethod.GET)
public String queryOrderInfo() throws InterruptedException {
    new CountDownLatch(1).await();
    return "您的订单信息查询完毕";
}

private String queryOrderInfo_error() throws InterruptedException {
    return "Fallback Hello";
}

测试过程中,超时熔断时间,可以设置的较大一些,也可以先不添加超时熔断的注解。

异步接口

java 复制代码
/**
 * curl http://localhost:8091/api/hystrix/stream
 */
@HystrixCommand(commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "150")
}, fallbackMethod = "stream_error"
)
@RequestMapping(value = "/stream", method = RequestMethod.GET)
public ResponseBodyEmitter stream(HttpServletResponse response) throws Exception {
    response.setContentType("text/event-stream");
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    ResponseBodyEmitter emitter = new ResponseBodyEmitter();
    emitter.send("异步响应");
    new Thread(() -> {
        for (int i = 0; i < 200; i++) {
            try {
                emitter.send("hi xfg-dev-tech-grafana\r\n" + i);
                Thread.sleep(250);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        emitter.complete();
    }).start();
    return emitter;
}

public ResponseBodyEmitter stream_error(HttpServletResponse response) throws IOException {
    response.setContentType("text/event-stream");
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Cache-Control", "no-cache");
    ResponseBodyEmitter emitter = new ResponseBodyEmitter();
    emitter.send("Err");
    emitter.complete();
    return emitter;
}

另外一个是一步响应接口,如果响应时间较长,则进入超时熔断方法中。
服务压测验证

yaml 复制代码
server:
  port: 8091
  # 1核2G内存,可默认配置 200;4核8G内存【accept-count=1000、max-threads=800、max-connections=10000】,线程数经验值800。线程池过大,cpu调度会消耗大量时间
  tomcat:
    mbeanregistry:
      enabled: true
    max-connections: 20 # 最大连接数  
    threads:
      max: 20         # 设定处理客户请求的线程的最大数目,决定了服务器可以同时响应客户请求的数,默认200
      min-spare: 10   # 初始化线程数,最小空闲线程数,默认是10
    accept-count: 10  # 等待队列长度

我们在 YML 文件中指定了 tomcat 的连接数配置为 20 个,处理线程最多也是20个。

同时还添加了监控空你暴露为true,这样 Grafana 才能监控到。
压测工具

不过这里为了让大家更加简单的压测下,我使用了 ApiPost 工具自带的压测,这样不需要自己再安装其他工具就可以简单压测下了。

你只要把2个接口配置到 ApiPost 就可以用一键压测工具进行压测。

所以如果你的应用配置的 Tomcat 连接数不合理,之后接口又容易超时,超时后又没有熔断,那么很容易就会把你的服务拖垮。很多新人在做一些对外的应用时,如果没有注意到这些,那么也是很容易宕机的。

好了 至此 Prometheus + Grafana 监控,验证 Hystrix 超时熔断 点点关注不迷路 老铁们!!!!!

相关推荐
爱琴孩1 天前
记一次Prometheus的WAL异常,导致服务器磁盘占用过高
prometheus·wal
Cheney Pan2 天前
第12篇 Prometheus 高可用与长期存储
prometheus
飞鸟真人3 天前
应用性能监测(APM)之 (五)Prometheus与OpenMetrics协议
prometheus·apm·open telemetry·openmetrics
Cheney Pan3 天前
第13篇 监控安全与权限治理
安全·prometheus
蓝胖的四次元口袋4 天前
Prometheus+Grafana知识梳理(2)
grafana·prometheus
Cheney Pan5 天前
第8篇 关键指标分析方法:RED/USE 与黄金信号
prometheus
打工仔折腾 AI6 天前
多台服务器日志分散难查?用Promtail+Loki+Grafana搭建集中检索平台
服务器·人工智能·后端·python·性能优化·django·grafana
Cheney Pan6 天前
第7篇 业务数据监控:SQL Exporter 与自定义业务指标
prometheus·exporter
Cheney Pan7 天前
第4篇 Spring Boot 应用监控:Micrometer 与 JVM 指标
jvm·spring boot·后端·prometheus
飞鸟真人7 天前
应用性能监测(APM)之 (四)Prometheus与Metrics集群存储
prometheus