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

作者:小凯
沉淀、分享、成长,让自己和他人都能有所收获!

本文的宗旨在于通过简单干净实践的方式教会读者,使用 Prometheus + Grafana 部署监控,同时结合监控了解到为什么需要使用 Hystrix 对接口进行超时熔断处理。

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

测试工程、监控Docker安装脚本、Grafana监控面板配置JSON
一、你是怎么挂的?
Tomcat 可分配的连接数就像厕所的坑位,一堆用户来上大号。本来4个坑位也够用了,因为用户来了也可以快速释放请求,不会长时间占用。但突然有这么一天,用户都拉肚子,一个进去就1个小时候,其余人都排队。最后给压垮了!
在这里插入图片描述

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

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

二、工程环境配置
这里做一个 SpringBoot 工程测试案例,并配合添加 Hystrix 熔断组件,以及使用 Grafana 监控来观察简单压测时连接数的消耗和接口性能的反馈。
在这里插入图片描述

  • 环境;jdk 1.8、Maven 3.6.x、Docker 环境
  • 代码;在 xfg-dev-tech-grafana 测试工程中提供了测试代码和环境安装

1. 配置修改
在这里插入图片描述

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

2. 安装监控
文件:docker-compose.yml

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 这样在后面迁移的时候也会非常容易。

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

地址:http://127.0.0.1:4000/dashboards (opens new window)- 打开仪表盘,导入监控面板配置。
在这里插入图片描述
在这里插入图片描述

  • 打开导入面板后,把案例工程中的 JSON 复制到导入面板的 JSON 里,点击 Load 这样就配置进去了。
  • 不过这会你还看不见数据,因为工程还没有启动,没有往里写入数据。

三、测试应用说明
1. 熔断配置

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.18</version>
</dependency>

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

@Configuration
public class HystrixConfig {

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

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

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

2.1 普通接口

/**
 * 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";
}
  • 测试过程中,超时熔断时间,可以设置的较大一些,也可以先不添加超时熔断的注解。
    2.2 异步接口
/**
 * 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;
}
  • 另外一个是一步响应接口,如果响应时间较长,则进入超时熔断方法中。

四、服务压测验证
1. 配置信息
application.yml

server:
  port: 8091
  # 12G内存,可默认配置 20048G内存【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 才能监控到。

2. 压测工具
压测工具有很多,包括;JMeter、ApacheBench、Siege (opens new window)。

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

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

3. 压测观察
在这里插入图片描述

  • 这里压测了下接口 http://localhost:8091/api/hystrix/stream 接口。因为这个接口设置了超时,可以看见,快速的就把连接数给占满了。
  • 所以如果你的应用配置的 Tomcat 连接数不合理,之后接口又容易超时,超时后又没有熔断,那么很容易就会把你的服务拖垮。很多新人在做一些对外的应用时,如果没有注意到这些,那么也是很容易宕机的。
<think>好的,我需要回答用户关于数据库熔断机制实现方案和故障处理的问题。首先,我要回顾一下熔断机制的基本概念,确保自己理解正确。根据用户提供的引用内容,熔断机制主要用于防止系统因依赖的服务故障而崩溃,通过监控失败率来触发熔断状态,停止请求,保护系统。引用[2]提到熔断的三个状态:关闭、断开和半开,这些状态转换是关键。 接下来,我需要将熔断机制具体应用到数据库层面。用户想了解数据库熔断的实现方案,所以需要结合数据库访问的特点。数据库作为关键服务,一旦过载或出现故障,可能导致整个系统瘫痪。因此,熔断机制在这里尤为重要。 首先,实现方案需要包括监控指标。数据库的常见问题可能包括连接超时、查询时间过长、错误率升高等。我需要考虑如何设置这些阈值,比如响应时间超过500ms触发熔断,错误率超过50%等。引用[3]提到Hystrix的默认阈值是5秒内20次失败,这可以作为参考。 然后是状态机设计。根据引用[2],熔断器的三个状态需要明确转换条件。例如,当错误率超过阈值,从关闭转为断开状态,停止所有数据库请求。经过设定的时间后进入半开状态,允许少量请求测试,成功则关闭熔断器,否则重新断开。 接下来是降级策略。当熔断触发时,系统需要如何处理。引用[4]指出降级和熔断的区别,这里可能需要提供默认值或缓存数据,避免直接返回错误,保证部分功能可用。例如,返回缓存数据或简化查询结果。 故障恢复机制也很重要。在半开状态下,如何逐步恢复流量,可能需要梯度增加请求量,确保数据库稳定。此外,熔断日志和报警能帮助运维快速响应问题,引用[3]中的Hystrix监控功能值得参考。 在具体实现上,使用中间件Hystrix或Resilience4j可以简化开发。例如,Hystrix的@HystrixCommand注解可以标记需要熔断保护的方法,设置超时和失败阈值。代码示例部分,用户可能需要看到如何配置这些参数,比如超时时间和熔断阈值。 故障处理方面,预防措施包括负载均衡、限流和索引优化,减少数据库压力。监控系统需要实时跟踪数据库健康状态,快速发现问题。应急处理则涉及快速切换主从、启用只读模式或临时关闭非核心功能,确保系统整体可用。 最后,总结部分需要强调熔断机制的重要性,并结合预防和监控措施,形成一个完整的解决方案。同时,根据用户提供的引用,确保引用标识正确,比如引用[2]和[3]关于状态和Hystrix的实现。 现在需要检查是否符合用户的所有要求:使用中文,数学公式正确,独立公式用$$...$$,生成相关问题,引用正确。确保没有使用任何markdown格式,代码块用三个反引号包裹,相关问题放在最后。此外,回答需结构清晰,分点说明,帮助用户逐步理解。</think>### 数据库熔断机制实现方案与故障处理 #### 一、数据库熔断机制的核心设计 1. **监控指标定义** 熔断机制需基于数据库访问的关键指标触发,常见指标包括: - 响应时间:若数据库查询平均耗时超过阈值(如$500ms$),触发熔断[^2] - 错误率:错误请求比例超过预设值(如$50\%$) - 连接池状态:活跃连接数超过容量限制(如$80\%$) 2. **状态机实现** 熔断器需维护三种状态(参考引用[2]): - **Closed(关闭)**:正常访问数据库,持续统计失败率 - **Open(断开)**:直接拒绝请求,返回预设错误(如`Fallback`数据) - **Half-Open(半开)**:允许少量试探请求,成功率达标则关闭熔断 $$熔断条件公式示例: \quad \text{触发条件} = \begin{cases} \text{Open} & \text{if } \frac{\text{失败请求数}}{\text{总请求数}} \geq \theta \\ \text{Half-Open} & \text{after } T \text{ 时间延迟} \end{cases}$$ 3. **降级策略** - 返回缓存数据(如Redis中预存的简化结果) - 提供默认值(如空列表或静态提示信息) - 简化查询逻辑(如仅返回必要字段)[^4] 4. **故障恢复机制** - 半开状态下逐步增加请求量(如梯度恢复$10\% \rightarrow 50\% \rightarrow 100\%$) - 熔断日志记录与报警通知(引用[3]中Hystrix监控模式) --- #### 二、具体实现方案示例(SpringCloud+Hystrix) ```java @HystrixCommand( fallbackMethod = "fallbackQuery", commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="1000"), //超时阈值 @HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="20"), //触发熔断的最小请求数 @HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="50"), //错误率阈值 @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="5000") //半开状态等待时间 } ) public List<Data> queryDatabase(String sql) { // 实际数据库访问逻辑 } public List<Data> fallbackQuery(String sql) { return Collections.singletonList(new Data("默认值")); //降级响应 } ``` --- #### 三、故障处理实践建议 1. **预防措施** - 负载均衡:通过读写分离、分库分表分散压力 - 限流机制:使用令牌桶算法控制请求速率(如$QPS \leq 1000$) - 索引优化:减少复杂查询的响应时间 2. **监控体系** - 实时监控Prometheus+Grafana跟踪$TPS$、$Latency$等指标 - 健康检查:定期执行`SELECT 1`探测数据库存活状态 3. **应急处理** - 快速切换:主从库故障时自动切换(如MySQL MHA) - 服务降级:非核心业务暂停写操作,仅提供只读服务 - 熔断日志分析:通过ELK(Elasticsearch, Logstash, Kibana)定位根本原因 --- #### 四、总结 数据库熔断机制通过**状态转换模型**和**阈值控制**,有效防止级联故障。需结合**预防性优化**(如索引设计)与**实时监控**(如Hystrix仪表盘)形成完整防护链[^3]。在触发熔断后,通过梯度恢复策略平衡系统稳定性与可用性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值