所有中间件指标接入 Prometheus——统一仪表盘实战

所有中间件指标接入 Prometheus 📖 前置阅读:本文假设读者已掌握 Prometheus + Grafana 的基础搭建和 PromQL 语法。如果还不熟悉,建议先阅读 Prometheus + Grafana 环境搭建与指标采集。 一、⚡ 你有 6 种中间件——但你知道一个请求穿过它们时发生了什么吗? 一个请求穿过整个微服务体系要走多少中间件? 浏览器请求 GET /api/orders/100: ① Gateway 收到请求——鉴权、路由匹配 ② Gateway 转发到 order-service(OpenFeign 或 Dubbo) ③ order-service 调 user-service(OpenFeign) ④ order-service 调 product-service(Dubbo) ⑤ 所有服务都在 Nacos 中发现对方 ⑥ Sentinel 在整个过程中限流/熔断 这 6 步中——任何一步慢了——整个请求就慢了 没有统一监控时——你不知道是 Gateway 慢了、OpenFeign 慢了、还是 Dubbo 慢了 这篇的目标——把每种中间件的指标接入 Prometheus,在一张 Grafana 仪表盘上看到全貌。 二、🏗️ 搭建教程——完整的 Docker Compose + Prometheus 配置 上一篇讲了 Prometheus + Grafana 的基础搭建——但那只是两个容器。这篇要接入 6 种中间件——需要一个完整的 Docker Compose 把 Prometheus、Grafana 和所有微服务编排在一起。 ...

十二月 18, 2022 · 9 分钟 · 1867 字 · yaomingye

Prometheus + Grafana 环境搭建与指标采集

Prometheus + Grafana 环境搭建 一、⚡ 微服务上线了——但你知道它现在是死是活吗? 前面写了 6 种中间件、拆了 5 个微服务、配了限流熔断、布了集群——一切看起来很完美。 凌晨 3 点,电话响了:“用户说下单超时——你看一下”。你打开电脑——但你能看什么? 没有监控时: ① SSH 到服务器——tail -f 看日志——满屏 WARN——不知道哪个先出问题 ② 查数据库——慢查询一大堆——不知道是不是今天的查询就变慢了 ③ 调 JVM 看线程——200 个线程在 BLOCKED——不知道是哪个接口引起的 → 30 分钟过去了——你在猜问题在哪 有了 Prometheus + Grafana: ① 打开 Grafana 看板——QPS 正常——但 RT 从 50ms 涨到 3s ② 看 JVM 仪表盘——线程数飚到 500——GC 频繁 ③ 看中间件面板——Dubbo 线程池满了——Sentinel 开始熔断 → 2 分钟定位——是商品服务的 Dubbo 线程池被打满了 监控不是运维的事——是每个后端开发必须掌握的技能。 二、🧩 Prometheus 是什么——拉模型 + 时序数据库 + PromQL 2.1 Prometheus 的 pull model——和传统监控的区别 大多数监控系统是push model——应用主动把指标推给监控 server。Prometheus 是pull model——它定期去应用那里"拉"指标: ...

十二月 17, 2022 · 5 分钟 · 1061 字 · yaomingye

Nacos 集群与生产部署——中间件整合总览

集群与生产部署——中间件整合总览 📖 前置阅读:本文假设读者已掌握 Nacos 的服务发现和配置中心机制。如果还不熟悉,建议先阅读前三篇:核心概念、服务发现、配置中心。 一、⚡ 单机 Nacos 挂了——整个微服务体系全部变瞎子 单机 Nacos 开发环境跑得挺好——但生产环境下,Nacos 是整个微服务体系的命脉: Nacos 挂了 → 后果: ① 新服务无法注册——滚动更新时新实例注册不上 ② 新调用无法发现——Consumer 拿不到最新实例列表(本地缓存还能撑一会) ③ 配置改不了——Sentinel 规则、Gateway 路由、业务开关全改不了 ④ Dashboard 看不了——不知道哪些服务在线、哪些不在线 虽然本地缓存能兜底——但这是"缓兵之计"不是"长久之计" Nacos 集群是必须的——而且要做高可用 二、🏗️ Nacos 集群架构——三个节点 + MySQL 2.1 为什么需要 MySQL? Nacos 内嵌了一个 Derby 数据库(单机默认)。集群模式下 必须用外部 MySQL——所有节点共享同一个数据源: Nacos 集群架构: ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Nacos 1 │ │ Nacos 2 │ │ Nacos 3 │ ← Nacos 节点(无状态) │ :8848 │ │ :8848 │ │ :8848 │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ └───────────────┼───────────────┘ │ ┌──────▼──────┐ │ MySQL │ ← 共享数据库——存注册信息和配置 │ (主从/集群) │ └─────────────┘ Nacos 节点之间用 Raft 协议选举 Leader → Leader 负责写 MySQL → Follower 从 MySQL 读数据并同步到内存 → 任何节点收到客户端请求——都能处理读请求 2.2 配置 MySQL -- 初始化 Nacos 数据库 -- 执行 Nacos 安装包中 conf/mysql-schema.sql -- 创建数据库 CREATE DATABASE IF NOT EXISTS nacos_config DEFAULT CHARACTER SET utf8mb4; -- 配置 Nacos 数据源 # nacos/conf/application.properties # ① MySQL 配置 spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://mysql-cluster:3306/nacos_config?useSSL=false&allowPublicKeyRetrieval=true db.user.0=nacos db.password.0=nacos_password_123 # ② 切换为集群模式 nacos.core.auth.enabled=true 2.3 集群节点配置 # nacos/conf/cluster.conf——每个节点一行 IP:Port # 注意:端口是 Raft 通信端口——默认 7848(不是 8848!) 10.0.1.11:7848 10.0.1.12:7848 10.0.1.13:7848 三、🐳 Docker Compose——一键启动 Nacos 集群 version: '3.8' services: # ===== MySQL——Nacos 共享存储 ===== mysql: image: mysql:8.0 container_name: nacos-mysql environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: nacos_config MYSQL_USER: nacos MYSQL_PASSWORD: nacos_password_123 ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql - ./mysql-schema.sql:/docker-entrypoint-initdb.d/01-schema.sql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s retries: 5 # ===== Nacos 集群——3 节点 ===== nacos1: image: nacos/nacos-server:v2.3.0 container_name: nacos1 depends_on: mysql: condition: service_healthy environment: - MODE=cluster - NACOS_SERVERS=nacos1:7848,nacos2:7848,nacos3:7848 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=mysql - MYSQL_SERVICE_PORT=3306 - MYSQL_SERVICE_DB_NAME=nacos_config - MYSQL_SERVICE_USER=nacos - MYSQL_SERVICE_PASSWORD=nacos_password_123 - NACOS_AUTH_ENABLE=true - NACOS_AUTH_IDENTITY_KEY=nacos - NACOS_AUTH_IDENTITY_VALUE=nacos - NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 ports: - "8848:8848" - "7848:7848" volumes: - nacos1-logs:/home/nacos/logs nacos2: image: nacos/nacos-server:v2.3.0 container_name: nacos2 depends_on: mysql: condition: service_healthy environment: - MODE=cluster - NACOS_SERVERS=nacos1:7848,nacos2:7848,nacos3:7848 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=mysql - MYSQL_SERVICE_PORT=3306 - MYSQL_SERVICE_DB_NAME=nacos_config - MYSQL_SERVICE_USER=nacos - MYSQL_SERVICE_PASSWORD=nacos_password_123 - NACOS_AUTH_ENABLE=true - NACOS_AUTH_IDENTITY_KEY=nacos - NACOS_AUTH_IDENTITY_VALUE=nacos - NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 ports: - "8849:8848" - "7849:7848" nacos3: image: nacos/nacos-server:v2.3.0 container_name: nacos3 depends_on: mysql: condition: service_healthy environment: - MODE=cluster - NACOS_SERVERS=nacos1:7848,nacos2:7848,nacos3:7848 - SPRING_DATASOURCE_PLATFORM=mysql - MYSQL_SERVICE_HOST=mysql - MYSQL_SERVICE_PORT=3306 - MYSQL_SERVICE_DB_NAME=nacos_config - MYSQL_SERVICE_USER=nacos - MYSQL_SERVICE_PASSWORD=nacos_password_123 - NACOS_AUTH_ENABLE=true ports: - "8850:8848" - "7850:7848" # ===== Prometheus——采集 Nacos 指标 ===== prometheus: image: prom/prometheus:v2.48.0 ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml volumes: mysql-data: nacos1-logs: prometheus.yml global: scrape_interval: 15s scrape_configs: - job_name: 'nacos' metrics_path: '/nacos/actuator/prometheus' static_configs: - targets: - 'nacos1:8848' - 'nacos2:8848' - 'nacos3:8848' 四、📊 Nacos 监控——Prometheus + Grafana Nacos 内置了 Prometheus 指标暴露——访问 http://nacos:8848/nacos/actuator/prometheus 即可获取。 ...

十二月 16, 2022 · 5 分钟 · 951 字 · yaomingye

Nacos 配置中心全操作

配置中心:从接入到动态刷新 📖 前置阅读:本文假设读者已掌握 Nacos 的基本概念和 @RefreshScope。如果还不熟悉,建议先阅读 Nacos 核心概念与快速上手。 一、⚡ 数据库密码改了——5 个服务 15 个实例要一个个改? 先来看看没有配置中心时的情况: 场景:MySQL 主库切换——数据库地址从 mysql-master-1 变成 mysql-master-2 没有配置中心: ① 改 5 个服务的 application.yml——每个服务改一次 ② 重新打包/重启 15 个实例——顺序不能错(先启 DB 相关的) ③ 改到一半发现有个服务漏了——生产故障 耗时:30 分钟 + 心跳加速 有了 Nacos 配置中心: ① 在 Nacos Dashboard 改一个配置——mysql.host ② 点发布——15 个实例自动收到推送 ③ @RefreshScope 的 Bean 自动重建——新配置生效 耗时:1 分钟 + 淡定 配置中心的价值就是一句话:改一次——推所有——不用重启。 二、🧩 配置的三级组织——shared-configs / extension-configs / 本地 Nacos 配置有三层——从最共享到最专属: shared-configs(共享配置) ← 所有服务通用的配置 ↓ 可以被覆盖 extension-configs(扩展配置) ← 一组服务共享的配置 ↓ 可以被覆盖 ${spring.application.name}-${profile}.${ext}(服务专属配置) ← 每个服务自己的配置 ↓ 兜底 application.yml(本地配置) ← 开发环境兜底——生产通常不放关键配置 2.1 三层配置在 yml 中怎么配 # bootstrap.yml(早于 application.yml 加载——连 Nacos 必须放这里) spring: application: name: order-service profiles: active: dev cloud: nacos: config: server-addr: localhost:8848 namespace: dev group: DEFAULT_GROUP file-extension: yaml # ① shared-configs——所有服务共享的公共配置 shared-configs: - data-id: common-mysql.yaml # 数据库公共配置——所有服务共用一个 DB 集群 group: DEFAULT_GROUP refresh: true # 允许动态刷新 - data-id: common-redis.yaml # Redis 公共配置 group: DEFAULT_GROUP refresh: true - data-id: common-log.yaml # 日志公共配置 group: DEFAULT_GROUP refresh: false # 日志配置不动态刷新——改日志级别才需要 # ② extension-configs——当前服务专属——比 shared 优先级高 extension-configs: - data-id: order-service-custom.yaml group: DEFAULT_GROUP refresh: true 2.2 Nacos Dashboard 中创建公共配置 Nacos Dashboard → 配置管理 → 配置列表 → 新建配置 ① common-mysql.yaml (DEFAULT_GROUP): spring: datasource: url: jdbc:mysql://mysql-master:3306/ username: app_user password: ${MYSQL_PASSWORD} # ← 密码用环境变量——不写在配置中心 hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 3000 ② common-redis.yaml (DEFAULT_GROUP): spring: redis: host: redis-cluster.internal port: 6379 lettuce: pool: max-active: 20 max-idle: 10 ③ order-service-dev.yaml (DEFAULT_GROUP): # 订单服务专属配置——覆盖或扩展公共配置 spring: datasource: url: jdbc:mysql://mysql-master:3306/order_db?useSSL=false # 覆盖——订单库 hikari: maximum-pool-size: 50 # 覆盖公共配置——订单服务连接池要大一些 app: order: max-items-per-order: 50 payment-timeout-seconds: 1800 2.3 配置加载的优先级——哪个生效? 当同一个配置在多个地方出现时——后加载的覆盖先加载的: ...

十二月 15, 2022 · 5 分钟 · 953 字 · yaomingye

Nacos 服务发现深度解析

服务发现深度解析 📖 前置阅读:本文假设读者已掌握 Nacos 的核心概念——命名空间/分组/服务/实例。如果还不熟悉,建议先阅读 Nacos 核心概念与快速上手。 一、⚡ 服务注册上去了——但为什么偶尔调不通? Nacos Dashboard 里看到服务是"健康"的——但 Feign 偶尔报 Connection Refused。排查后发现:那个实例 5 分钟前就挂了——Nacos 还没把它剔掉。 服务发现不是"注册上去了就完了"——你要理解它背后的机制:心跳怎么维护?挂了的实例多久被剔除?本地缓存的作用是什么? 二、🔄 服务注册流程全景 sequenceDiagram participant Provider as 服务提供方\nuser-service participant Nacos participant Consumer as 服务调用方\norder-service Provider->>Nacos: ① 注册:我是 user-service,地址 10.0.1.1:8081 Note over Provider,Nacos: Provider 启动时向 Nacos 注册 Provider->>Nacos: ② 心跳:我还活着(每 5s) Note over Provider,Nacos: 健康的实例定时发心跳 Consumer->>Nacos: ③ 订阅:我要找 user-service Nacos-->>Consumer: ④ 返回实例列表:[10.0.1.1:8081, 10.0.1.2:8081] Note over Nacos,Consumer: Consumer 拉一次——后续 Nacos Push 变更 Consumer->>Provider: ⑤ 直连调用——GET /api/users/1 Note over Consumer,Provider: 选一个实例——通过负载均衡 Note over Nacos: 实例不发心跳 15s → 不健康\n30s → 剔除 关键点——Nacos 不参与业务流量:服务注册/发现只在"找地址"阶段经过 Nacos。一旦 Consumer 拿到了实例列表——后续的 RPC 调用是直连 Provider——不经过 Nacos。 ...

十二月 14, 2022 · 4 分钟 · 809 字 · yaomingye

Nacos 核心概念与快速上手

核心概念与快速上手 一、⚡ 服务多了——两个最头疼的问题 微服务写到第 6 个的时候——你会发现两个问题越来越痛: 问题 ①:服务之间怎么找到对方? OrderService 调 UserService——以前一个 IP:Port 写死就行了 现在 UserService 有 3 个实例——10.0.1.1:8081、10.0.1.2:8081、10.0.1.3:8081 明天扩容到 5 个——OrderService 难道重新改配置上线? → 需要"服务发现"——调用方不关心实例在哪——找注册中心问 问题 ②:改了配置怎么让所有服务生效? 数据库连接池从 20 改到 50——5 个服务 × 3 个实例 = 15 个 yml 文件要改 改完还得一个个重启——重启顺序还不能乱 → 需要"配置中心"——一处修改——所有实例自动感知 这两个问题的答案就是 Nacos——一个组件同时搞定服务发现和配置中心。 二、🧩 Nacos 是什么——一句话 Nacos(NAming and COnfiguration Service)= 服务发现 + 配置中心。它是阿里开源的微服务基础设施——Spring Cloud Alibaba 的核心组件。 在 Nacos 之前——Spring Cloud 微服务需要两个组件: 没有 Nacos 的时代: Eureka(服务注册/发现) + Spring Cloud Config(配置中心) + Spring Cloud Bus(配置刷新) 三个组件——三套配置——三种部署方式 有了 Nacos: Nacos 一个组件 = Eureka + Config + Bus 一套配置——一种部署方式——学习成本砍一半 三、🏗️ 部署 Nacos Server——3 分钟跑起来 # 方式一:Docker——最快 docker run -d \ --name nacos \ -p 8848:8848 \ -p 9848:9848 \ -e MODE=standalone \ nacos/nacos-server:v2.3.0 # 方式二:直接运行——下载后解压 # https://github.com/alibaba/nacos/releases # 解压后 cd nacos/bin # Windows: startup.cmd -m standalone # Linux/Mac: sh startup.sh -m standalone # 访问 http://localhost:8848/nacos # 用户名/密码:nacos/nacos 两个端口的作用: ...

十二月 13, 2022 · 3 分钟 · 636 字 · yaomingye

OpenFeign 生产实战——Nacos + Sentinel + 性能调优

生产实战:Nacos + Sentinel + 性能调优 📖 前置阅读:本文假设读者已掌握 OpenFeign 的配置和容错机制。如果还不熟悉,建议先阅读 OpenFeign 核心概念与快速上手 和 进阶——配置、拦截器与容错。 一、⚡ Feign 调通了——但生产环境的三块拼图还缺着 前两篇搞定了 Feign 的基本用法、超时、重试、拦截器、Fallback。但生产环境还有三件事必须做: ① Feign + Nacos —— 不再写死 URL——服务自动发现、负载均衡 ② Feign + Sentinel —— 被调服务慢/挂了——熔断降级保护调用方 ③ Feign + 性能调优 —— Gzip 压缩、连接池、异步并发 二、🧩 Feign + Nacos 服务发现——零 URL 硬编码 2.1 依赖 <dependencies> <!-- OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- LoadBalancer——Feign 自动集成——不需要显式引入 --> </dependencies> 2.2 配置 spring: application: name: order-service cloud: nacos: discovery: server-addr: localhost:8848 namespace: production # 命名空间——隔离环境 group: ORDER_GROUP # 分组 // Feign 接口——只声明服务名,不写 URL @FeignClient(name = "user-service") // Nacos 中有 user-service 这个服务 public interface UserClient { @GetMapping("/api/users/{userId}") User getUser(@PathVariable("userId") Long userId); } 2.3 负载均衡策略 Feign 默认用 Spring Cloud LoadBalancer——轮询策略。想换成随机或加权策略: ...

十二月 12, 2022 · 7 分钟 · 1285 字 · yaomingye

OpenFeign 进阶——配置、拦截器与容错

进阶指南:配置、拦截器与容错 📖 前置阅读:本文假设读者已掌握 OpenFeign 的基本用法——@FeignClient、注解映射。如果还不熟悉,建议先阅读 OpenFeign 核心概念与快速上手。 一、⚡ 调通了——但第二天线上就出问题 Feign 的基本调用 5 分钟搞定。但一上生产——问题一个接一个: 问题 ①:用户服务偶尔慢 2 秒——订单服务的 Feign 一直等——线程全卡死 → 需要超时配置 问题 ②:网络抖动——请求偶尔失败——直接抛异常给用户 → 需要重试机制 问题 ③:用户服务需要 Token 鉴权——每次调 Feign 都要手动传 Header → 需要拦截器自动注入 问题 ④:用户服务挂了——Feign 调不通——订单服务的线程池被占满 → 需要 Fallback 降级 问题 ⑤:排查问题——Feign 到底发了什么请求?返回了什么? → 需要日志 这一篇把以上每个问题都给出具体配置和代码。 二、⏱️ 超时与重试——Feign 最容易被忽略的配置 2.1 默认的超时太长了 Feign 底层用 Ribbon(老版本)或 LoadBalancer(新版本)做负载均衡。默认超时: 参数 默认值 说明 connect-timeout 1s 建立 TCP 连接的超时——默认还好 read-timeout 60s 等响应的超时——太长了!一个慢请求能卡 60 秒 # application.yml——Feign 超时配置 spring: cloud: openfeign: client: config: # ① 全局配置——对所有 FeignClient 生效 default: connect-timeout: 3000 # 建连接最多等 3s read-timeout: 5000 # 等响应最多等 5s logger-level: BASIC # ② 按服务配置——针对特定服务 user-service: # 这个名字和 @FeignClient(name="user-service") 对应 connect-timeout: 2000 read-timeout: 3000 # 用户服务是核心——超时设短点 product-service: connect-timeout: 5000 read-timeout: 10000 # 商品服务偶尔慢——多给点时间 2.2 重试——哪些请求能重试,哪些不能 spring: cloud: openfeign: client: config: default: retryer: com.example.feign.DefaultRetryer # 自定义重试器 // 自定义重试策略 @Configuration public class FeignRetryConfig { @Bean public Retryer feignRetryer() { // 参数:period(初始间隔), maxPeriod(最大间隔), maxAttempts(最多尝试次数) // 下面 = 初始等 100ms → 每次乘 1.5 → 最多重试 3 次(总共 4 次) return new Retryer.Default(100, 1500, 3); } } 重试的时间线: 第 1 次请求 → 失败 → 等 100ms 第 2 次请求 → 失败 → 等 250ms 第 3 次请求 → 失败 → 等 625ms 第 4 次请求 → 成功 → 返回 如果第 4 次也失败 → 抛异常 ⚠️ 新手提示:POST 请求不要重试!如果创建订单的 POST 请求超时——Feign 自动重试——用户被扣了两次钱。GET 可以重试(幂等),POST/PUT/DELETE 绝不重试。要控制这个——用 @FeignClient 的 configuration 属性对不同接口用不同的重试策略。 ...

十二月 11, 2022 · 6 分钟 · 1144 字 · yaomingye

OpenFeign 核心概念与快速上手

核心概念与快速上手 一、⚡ 微服务拆了——然后呢? 你把单体应用拆成了用户服务和订单服务。数据库拆了、代码拆了、团队也拆了。然后订单服务需要查用户信息: // 拆分之前——同一个 JVM,直接调方法 User user = userService.getUserById(userId); // 拆分之后——跨 JVM、跨机器 // 你必须写一堆 HTTP 调用代码 RestTemplate restTemplate = new RestTemplate(); String url = "http://user-service:8081/api/users/" + userId; User user = restTemplate.getForObject(url, User.class); 这段代码有四个问题: 问题 RestTemplate 写法 怎么解决 URL 硬编码 "http://user-service:8081/api/users/" 服务名代替 IP:Port——自动发现 参数拼接繁琐 url + userId 手动拼 声明参数——自动放到 URL 上 返回值无类型保障 getForObject(url, User.class) 手动指定 接口方法声明返回类型——编译器检查 和本地调用差距太大 完全不同的调用方式——学习成本 写法完全和本地方法一样 OpenFeign 解决的就是这个问题——让你调远程服务和调本地方法一样,而且完全不侵入被调方的接口。 二、🧩 OpenFeign 是什么——一句话 OpenFeign 是一个声明式 HTTP 客户端。你只需要写一个 Java 接口 + 注解,Feign 自动帮你生成 HTTP 调用的实现。 ...

十二月 10, 2022 · 4 分钟 · 842 字 · yaomingye

Sentinel 系统规则与生产部署

Sentinel 生产部署 📖 前置阅读:本文假设读者已掌握 Sentinel 流控和熔断规则。如果还不熟悉,建议先阅读前三篇:核心概念、流控规则、熔断降级。 一、⚡ 流控和熔断都配了——但整个机器的 CPU 飙到 95% 了 流控规则保护的是单个接口——“getUser 每秒最多 100 个”。“熔断规则保护的是接口自身故障——“getUser 50% 慢调用就熔断”。 但这些规则不保护整个机器——如果 20 个接口各自都没超过自己的 QPS 阈值,但加起来把机器的 CPU 打满了——所有接口不可用。 系统规则(System Rule)解决的就是这个问题——从整个应用的层面做自适应保护。 二、🧬 系统自适应保护——不配具体 QPS,配"健康指标” 2.1 五种系统规则 // 系统规则——对整个服务生效——不是针对某个资源 SystemRule systemRule = new SystemRule(); // ① Load 保护——系统负载(仅 Linux)超过阈值时限流 systemRule.setHighestSystemLoad(4.0); // CPU 核数——如 4 核 CPU // 系统 Load > 4.0 时——所有入口 QPS 自动降到 (Load / 当前Load) * 当前QPS // ② CPU 使用率保护 systemRule.setHighestCpuUsage(0.8); // CPU 使用率 > 80% 时——拒绝新的入口请求 // ③ 平均 RT 保护 systemRule.setAvgRt(100); // 所有入口的平均 RT > 100ms 时——限流 // ④ 最大并发线程数 systemRule.setMaxThread(200); // 并发线程数 > 200——拒绝新请求 // ⑤ 入口 QPS——这个最直接 systemRule.setQps(500); // 所有入口(不管是哪个资源)——总 QPS > 500 系统规则 指标 阈值建议 适用场景 Load 系统 Load ≤ CPU 核数 Linux 环境——最推荐 CPU 使用率 CPU usage ≤ 80% 跨平台——和 Load 二选一 平均 RT 所有入口平均 RT ≤ 正常值 × 2 服务变慢时自动降 QPS 并发线程数 并发线程数 ≤ 线程池大小 防止线程池满 入口 QPS 总 QPS ≤ 压测值 × 80% 简单粗暴——兜底方案 2.2 系统规则的最佳组合 @Component public class SystemRuleInitializer implements ApplicationRunner { @Override public void run(ApplicationArguments args) { List<SystemRule> rules = new ArrayList<>(); // 规则 1:Load 保护——系统负载过高时自动降 QPS SystemRule loadRule = new SystemRule(); loadRule.setHighestSystemLoad(4.0); rules.add(loadRule); // 规则 2:平均 RT 保护——接口变慢时自动减速 SystemRule rtRule = new SystemRule(); rtRule.setAvgRt(200); rules.add(rtRule); // 规则 3:并发线程数保护——防止线程池满 SystemRule threadRule = new SystemRule(); threadRule.setMaxThread(300); rules.add(threadRule); SystemRuleManager.loadRules(rules); } } 系统规则是整个 JVM 级别的——不需要指定资源名。它的作用范围是所有入口(所有经过 Sentinel 保护的入口流量的汇总)。 ...

十二月 9, 2022 · 5 分钟 · 1042 字 · yaomingye
Cat Radio