本文档风哥主要介绍TiDB关键监控指标与告警配置,包括关键监控指标的概念、TiDB关键监控指标介绍、告警系统的概念与特点、监控指标规划、告警策略规划、告警规则配置等内容,风哥教程参考TiDB官方文档监控告警相关内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 关键监控指标的概念
关键监控指标是指能够反映系统运行状态和性能的重要指标,通过监控这些指标可以及时发现系统异常和性能瓶颈。关键监控指标通常具有以下特点:学习交流加群风哥微信: itpux-com
- 能够反映系统的核心运行状态
- 对系统性能和可靠性有重要影响
- 能够提前预警潜在问题
- 易于理解和分析
- 具有明确的阈值和告警标准
1.2 TiDB关键监控指标介绍
TiDB的关键监控指标主要包括以下几类:
## 1. TiDB组件指标
– QPS:每秒查询数
– 延迟:查询执行时间
– 错误率:错误查询占比
– 连接数:当前连接数量
– 内存使用:内存占用情况
– CPU使用:CPU使用率
## 2. TiKV组件指标
– 存储使用:总存储和可用存储
– 读写延迟:读操作和写操作的延迟
– 并发请求:当前并发请求数
– RocksDB指标:压缩、读写放大
– 调度指标:leader数量、region数量
## 3. PD组件指标
– 集群状态:健康状态
– 调度指标:调度次数、调度延迟
– 存储容量:总容量、可用容量
– 性能指标:API延迟、QPS
## 4. TiFlash组件指标
– 读写延迟:读操作和写操作的延迟
– 存储使用:总存储和可用存储
– 复制状态:数据复制状态
## 5. 主机指标
– CPU使用率:各核心CPU使用情况
– 内存使用率:内存使用情况
– 磁盘使用率:磁盘空间使用情况
– 磁盘IO:磁盘读写性能
– 网络流量:网络收发数据量风哥提示:
1.3 告警系统的概念与特点
告警系统是监控系统的重要组成部分,用于在系统出现异常时及时通知相关人员。告警系统通常具有以下特点:
- 及时性:能够及时发现和通知异常
- 准确性:能够准确判断异常情况
- 可配置性:支持灵活的告警规则配置
- 多渠道:支持多种告警通知渠道
- 可管理性:支持告警的分级、分组和抑制
Part02-生产环境规划与建议
2.1 监控指标规划
监控指标规划要点:
## 1. 指标分类
– 核心指标:必须监控的关键指标
– 重要指标:需要监控的重要指标
– 辅助指标:根据需要选择监控的指标
## 2. 指标选择原则
– 相关性:与系统性能和可靠性相关
– 可操作性:能够通过指标发现和解决问题
– 可监控性:能够准确采集和监控
– 可分析性:易于分析和理解
## 3. 采集频率规划
– 核心指标:10-15秒
– 重要指标:30秒-1分钟
– 辅助指标:1-5分钟
## 4. 存储规划
– 短期存储:7-14天
– 长期存储:30-90天
– 归档存储:根据需要
2.2 告警策略规划
告警策略规划要点:
## 1. 告警级别
– 紧急(Critical):需要立即处理的严重问题
– 严重(Severe):需要尽快处理的重要问题
– 警告(Warning):需要关注的潜在问题
– 信息(Info):一般信息性通知
## 2. 告警频率
– 紧急:立即通知,5分钟未处理升级
– 严重:立即通知,15分钟未处理升级
– 警告:定期通知,1小时未处理升级
– 信息:每日汇总通知
## 3. 告警抑制
– 同一问题的多个告警只发送一次
– 低级别告警在高级别告警触发时被抑制
– 维护期间暂时抑制告警
## 4. 告警分组
– 按组件分组:TiDB、TiKV、PD、TiFlash
– 按主机分组:按服务器分组
– 按业务分组:按业务系统分组
2.3 告警渠道配置
告警渠道配置建议:
- 邮件:适合所有级别的告警,作为基础通知渠道
- 短信:适合紧急和严重级别的告警,确保及时通知
- 微信:适合所有级别的告警,方便移动查看
- 企业微信/钉钉:适合团队协作,便于集体处理
- Slack:适合开发团队,便于集成其他工具
- 电话:适合特别紧急的告警,确保有人响应
Part03-生产环境项目实施方案
3.1 关键监控指标配置
3.1.1 TiDB关键指标配置
## 1. QPS指标
– 指标名称:tidb_server_qps学习交流加群风哥QQ113257174
– 采集频率:15秒
– 监控目标:所有TiDB实例
– 告警阈值:
– 警告:QPS > 8000
– 严重:QPS > 10000
## 2. 延迟指标
– 指标名称:tidb_server_handle_query_duration_seconds
– 采集频率:15秒
– 监控目标:所有TiDB实例
– 告警阈值:
– 警告:P99 > 0.5秒
– 严重:P99 > 1秒
## 3. 错误率指标
– 指标名称:tidb_server_errors_total
– 采集频率:15秒
– 监控目标:所有TiDB实例
– 告警阈值:
– 警告:错误率 > 0.5%
– 严重:错误率 > 1%
## 4. 连接数指标
– 指标名称:tidb_server_connections
– 采集频率:30秒
– 监控目标:所有TiDB实例
– 告警阈值:
– 警告:连接数 > 800
– 严重:连接数 > 1000
3.1.2 TiKV关键指标配置
## 1. 存储使用指标
– 指标名称:tikv_store_capacity, tikv_store_available_size
– 采集频率:1分钟
– 监控目标:所有TiKV实例
– 告警阈值:
– 警告:使用率 > 70%
– 严重:使用率 > 85%
## 2. 读写延迟指标
– 指标名称:tikv_server_request_duration_seconds
– 采集频率:15秒
– 监控目标:所有TiKV实例
– 告警阈值:
– 警告:P99 > 0.1秒
– 严重:P99 > 0.2秒
## 3. 并发请求指标
– 指标名称:tikv_server_current_requests
– 采集频率:15秒
– 监控目标:所有TiKV实例
– 告警阈值:
– 警告:并发请求 > 1000
– 严重:并发请求 > 2000
## 4. RocksDB指标
– 指标名称:tikv_rocksdb_write_amplification, tikv_rocksdb_read_amplification
– 采集频率:1分钟
– 监控目标:所有TiKV实例
– 告警阈值:
– 警告:写放大 > 10
– 严重:写放大 > 20
3.1.3 PD关键指标配置
## 1. 集群状态指标
– 指标名称:pd_cluster_status
– 采集频率:15秒
– 监控目标:所有PD实例
– 告警阈值:
– 严重:状态 != 健康
## 2. 调度指标
– 指标名称:pd_scheduler_schedule_counter
– 采集频率:30秒
– 监控目标:所有PD实例
– 告警阈值:
– 警告:调度失败率 > 10%
– 严重:调度失败率 > 20%
## 3. 存储容量指标
– 指标名称:pd_cluster_total_capacity, pd_cluster_available_capacity
– 采集频率:1分钟
– 监控目标:所有PD实例
– 告警阈值:
– 警告:使用率 > 70%
– 严重:使用率 > 85%
## 4. 性能指标
– 指标名称:pd_server_handle_request_duration_seconds
– 采集频率:30秒
– 监控目标:所有PD实例
– 告警阈值:
– 警告:P99 > 0.1秒
– 严重:P99 > 0.2秒
3.2 告警规则配置
3.2.1 告警规则文件配置
$ mkdir -p /tidb/app/prometheus/alerts
$ cat > /tidb/app/prometheus/alerts/tidb_alerts.yml << EOF groups: - name: tidb rules: - alert: TiDBDown expr: up{job="tidb"} == 0 for: 5m labels: severity: critical annotations: summary: "TiDB down" description: "TiDB instance {{ $labels.instance }} is down for more than 5 minutes" - alert: TiDBHighQPS expr: sum(rate(tidb_server_qps[5m])) by (instance) > 10000
for: 5m
labels:
severity: warning
annotations:
summary: “TiDB high QPS”
description: “TiDB instance {{ $labels.instance }} has high QPS: {{ $value }}”
– alert: TiDBHighErrorRate
expr: sum(rate(tidb_server_errors_total[5m])) by (instance) / sum(rate(tidb_server_qps[5m])) by (instance) > 0.01
for: 5m
labels:
severity: warning
annotations:
summary: “TiDB high error rate”
description: “TiDB instance {{ $labels.instance }} has high error rate: {{ $value }}”
– alert: TiDBHighConnections
expr: tidb_server_connections{job=”tidb”} > 1000
for: 5m
labels:
severity: warning
annotations:
summary: “TiDB high connections”
description: “TiDB instance {{ $labels.instance }} has high connections: {{ $value }}”
EOF
$ cat > /tidb/app/prometheus/alerts/tikv_alerts.yml << EOF
groups:
- name: tikv
rules:
- alert: TiKVDown
expr: up{job="tikv"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "TiKV down"
description: "TiKV instance {{ $labels.instance }} is down for more than 5 minutes"
- alert: TiKVHighStorageUsage
expr: (1 - tikv_store_available_size / tikv_store_capacity) > 0.85
for: 10m
labels:
severity: critical
annotations:
summary: “TiKV high storage usage”
description: “TiKV instance {{ $labels.instance }} has high storage usage: {{ $value | humanizePercentage }}”
– alert: TiKVHighLatency
expr: histogram_quantile(0.99, sum(rate(tikv_server_request_duration_seconds_bucket[5m])) by (instance, le)) > 0.2
for: 5m
labels:
severity: warning
annotations:
summary: “TiKV high latency”
description: “TiKV instance {{ $labels.instance }} has high latency: {{ $value }}s”
– alert: TiKVHighConcurrency
expr: sum(tikv_server_current_requests) by (instance) > 2000
for: 5m
labels:
severity: warning
annotations:
summary: “TiKV high concurrency”
description: “TiKV instance {{ $labels.instance }} has high concurrency: {{ $value }}”
EOF
$ cat > /tidb/app/prometheus/alerts/pd_alerts.yml << EOF
groups:
- name: pd
rules:
- alert: PDDown
expr: up{job="pd"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "PD down"
description: "PD instance {{ $labels.instance }} is down for more than 5 minutes"
- alert: PDClusterUnhealthy
expr: pd_cluster_status{type="health"} != 1
for: 5m
labels:
severity: critical
annotations:
summary: "PD cluster unhealthy"
description: "PD cluster is unhealthy"
- alert: PDHighStorageUsage
expr: (1 - pd_cluster_available_capacity / pd_cluster_total_capacity) > 0.85
for: 10m
labels:
severity: critical
annotations:
summary: “PD high storage usage”
description: “PD cluster has high storage usage: {{ $value | humanizePercentage }}”
– alert: PDScheduleFailure
expr: rate(pd_scheduler_schedule_counter{type=”fail”}[5m]) / rate(pd_scheduler_schedule_counter{type=”total”}[5m]) > 0.2
for: 5m
labels:
severity: warning
annotations:
summary: “PD schedule failure”
description: “PD schedule failure rate is high: {{ $value | humanizePercentage }}”
EOF
# 重新加载配置
$ curl -X POST http://localhost:9090/-/reload
3.2.2 AlertManager配置
$ cat > /tidb/app/alertmanager/alertmanager.yml << EOF global: resolve_timeout: 5m smtp_smarthost: 'smtp.example.com:587' smtp_from: 'alertmanager@fgedu.net.cn' smtp_auth_username: 'alertmanager' smtp_auth_password: 'password' wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/' wechat_api_corp_id: 'your_corp_id' wechat_api_secret: 'your_secret' route: group_by: ['alertname', 'cluster', 'service'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'default-receiver' routes: - match: severity: critical receiver: 'critical-receiver' - match: severity: warning receiver: 'warning-receiver' receivers: - name: 'default-receiver' email_configs: - to: 'admin@fgedu.net.cn' send_resolved: true - name: 'critical-receiver' email_configs: - to: 'admin@fgedu.net.cn' send_resolved: true wechat_configs: - corp_id: 'your_corp_id' api_url: 'https://qyapi.weixin.qq.com/cgi-bin/' to_party: '1' agent_id: '1000002' api_secret: 'your_secret' message: '{{ template "wechat.default.message" . }}' - name: 'warning-receiver' email_configs: - to: 'admin@fgedu.net.cn' send_resolved: true wechat_configs: - corp_id: 'your_corp_id' api_url: 'https://qyapi.weixin.qq.com/cgi-bin/' to_party: '1' agent_id: '1000002' api_secret: 'your_secret' message: '{{ template "wechat.default.message" . }}' inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster', 'service'] EOF # 启动AlertManager $ systemctl restart alertmanager # 验证AlertManager状态 $ systemctl status alertmanager # 输出示例 ● alertmanager.service - AlertManager Loaded: loaded (/etc/systemd/system/alertmanager.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2026-04-09 10:00:00 CST; 5min ago Main PID: 12346 (alertmanager) Tasks: 5 Memory: 64.0M CPU: 2% CGroup: /system.slice/alertmanager.service └─12346 /tidb/app/alertmanager/alertmanager --config.file=/tidb/app/alertmanager/alertmanager.yml
3.3 告警管理
3.3.1 告警状态管理
http://192.168.1.50:9093
# 告警状态
– firing:正在触发的告警
– resolved:已解决的告警
# 告警分组
– 按alertname分组:相同名称的告警分组
– 按cluster分组:相同集群的告警分组
– 按service分组:相同服务的告警分组
# 告警抑制
– 高级别告警抑制低级别告警
– 同一问题的多个告警只显示一个
# 告警路由
– 根据标签将告警路由到不同的接收器
– 支持多级路由
3.3.2 告警通知管理
– 邮件通知:配置SMTP服务器
– 微信通知:配置企业微信应用
– 短信通知:配置短信网关
– 电话通知:配置电话网关
– Slack通知:配置Slack webhook
# 通知模板
$ cat > /tidb/app/alertmanager/templates/default.tmpl << EOF
{{ define "wechat.default.message" }}
{{ range .Alerts }}
告警级别: {{ .Labels.severity }}
告警类型: {{ .Labels.alertname }}
告警主机: {{ .Labels.instance }}
告警详情: {{ .Annotations.description }}
触发时间: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
{{ end }}
{{ end }}
EOF
# 测试告警通知
$ curl -X POST http://localhost:9093/api/v1/alerts -d '[{
"labels": {
"alertname": "TestAlert",
"severity": "critical",
"instance": "test.fgedu.net.cn",
"service": "tidb"
},
"annotations": {
"summary": "Test alert",
"description": "This is a test alert"
}
}]'
Part04-生产案例与实战讲解
4.1 关键监控指标使用案例
4.1.1 分析TiDB性能问题
– 登录Grafana
– 打开TiDB Overview面板
– 查看QPS指标
# 步骤2:分析QPS趋势
– 观察QPS随时间的变化
– 识别QPS异常波动
– 分析QPS峰值出现的原因
# 步骤3:查看延迟指标
– 打开TiDB Overview面板
– 查看查询延迟指标
– 分析延迟与QPS的关系
# 步骤4:查看错误率
– 打开TiDB Overview面板
– 查看错误率指标
– 分析错误类型和原因
# 步骤5:定位问题
– 根据监控指标定位性能瓶颈
– 分析SQL语句
– 优化数据库配置
# 输出示例
QPS: 12000 (峰值)
延迟: P99 = 1.2秒 (异常)
错误率: 1.5% (异常)
# 问题原因:
– 某条SQL语句执行效率低下
– 导致QPS升高、延迟增加、错误率上升
# 解决方案:
– 优化SQL语句
– 添加索引
– 调整TiDB参数
4.1.2 分析TiKV存储问题
– 登录Grafana
– 打开TiKV面板
– 查看存储使用指标
# 步骤2:分析存储趋势
– 观察存储使用随时间的变化
– 识别存储增长异常
– 分析存储增长原因
# 步骤3:查看TiKV读写延迟
– 打开TiKV面板
– 查看读写延迟指标
– 分析延迟与存储使用的关系
# 步骤4:查看RocksDB指标
– 打开TiKV面板
– 查看RocksDB指标
– 分析压缩、读写放大等
# 步骤5:定位问题
– 根据监控指标定位存储瓶颈
– 分析数据分布
– 优化存储配置
# 输出示例
存储使用率: 85% (警告)
写延迟: P99 = 0.15秒 (异常)
写放大: 15 (异常)
# 问题原因:
– 数据分布不均匀
– RocksDB压缩不及时
– 存储容量不足
# 解决方案:
– 调整TiKV参数
– 增加存储容量
– 优化数据分布
4.2 告警配置实战
4.2.1 配置TiDB告警
$ cat > /tidb/app/prometheus/alerts/tidb_alerts.yml << EOF groups: - name: tidb rules: - alert: TiDBDown expr: up{job="tidb"} == 0 for: 5m labels: severity: critical annotations: summary: "TiDB down" description: "TiDB instance {{ $labels.instance }} is down for more than 5 minutes" - alert: TiDBHighQPS expr: sum(rate(tidb_server_qps[5m])) by (instance) > 10000
for: 5m
labels:
severity: warning
annotations:
summary: “TiDB high QPS”
description: “TiDB instance {{ $labels.instance }} has high QPS: {{ $value }}”
– alert: TiDBHighErrorRate
expr: sum(rate(tidb_server_errors_total[5m])) by (instance) / sum(rate(tidb_server_qps[5m])) by (instance) > 0.01
for: 5m
labels:
severity: warning
annotations:
summary: “TiDB high error rate”
description: “TiDB instance {{ $labels.instance }} has high error rate: {{ $value }}”
– alert: TiDBHighConnections
expr: tidb_server_connections{job=”tidb”} > 1000
for: 5m
labels:
severity: warning
annotations:
summary: “TiDB high connections”
description: “TiDB instance {{ $labels.instance }} has high connections: {{ $value }}”
EOF
# 步骤2:重新加载配置
$ curl -X POST http://localhost:9090/-/reload
# 步骤3:验证告警规则
$ curl http://localhost:9090/api/v1/rules
# 输出示例
{
“status”: “success”,
“data”: {
“groups”: [
{
“name”: “tidb”,
“file”: “/tidb/app/prometheus/alerts/tidb_alerts.yml”,
“rules”: [
{
“name”: “TiDBDown”,
“query”: “up{job=\”tidb\”} == 0″,
“duration”: 300,
“labels”: {
“severity”: “critical”
},
“annotations”: {
“description”: “TiDB instance {{ $labels.instance }} is down for more than 5 minutes”,
“summary”: “TiDB down”
}
},
…
]
}
]
}
}
4.2.2 配置告警渠道
$ cat > /tidb/app/alertmanager/alertmanager.yml << EOF global: resolve_timeout: 5m smtp_smarthost: 'smtp.example.com:587' smtp_from: 'alertmanager@fgedu.net.cn' smtp_auth_username: 'alertmanager' smtp_auth_password: 'password' route: group_by: ['alertname', 'cluster', 'service'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'email' receivers: - name: 'email' email_configs: - to: 'admin@fgedu.net.cn' send_resolved: true inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster', 'service'] EOF # 步骤2:重启AlertManager $ systemctl restart alertmanager # 步骤3:测试告警通知 $ curl -X POST http://localhost:9093/api/v1/alerts -d '[{ "labels": { "alertname": "TestAlert", "severity": "critical", "instance": "test.fgedu.net.cn", "service": "tidb" }, "annotations": { "summary": "Test alert", "description": "This is a test alert" } }]' # 步骤4:查看告警状态 $ curl http://localhost:9093/api/v1/alerts # 输出示例 { "status": "success", "data": { "alerts": [ { "status": "firing", "labels": { "alertname": "TestAlert", "instance": "test.fgedu.net.cn", "service": "tidb", "severity": "critical" }, "annotations": { "description": "This is a test alert", "summary": "Test alert" }, "startsAt": "2026-04-09T02:00:00Z", "endsAt": null, "generatorURL": "" } ] } }
4.3 告警处理流程
4.3.1 告警处理步骤
## 1. 告警接收
– 接收告警通知(邮件、微信、短信等)
– 确认告警内容和级别
– 记录告警信息
## 2. 告警分析
– 登录监控系统查看详细信息
– 分析告警原因
– 评估影响范围
## 3. 告警处理
– 根据告警级别采取相应措施
– 紧急告警:立即处理
– 严重告警:尽快处理
– 警告:计划处理
– 信息:关注即可
## 4. 问题解决
– 实施解决方案
– 验证问题是否解决
– 记录解决方案
## 5. 告警关闭
– 确认问题已解决
– 等待告警自动关闭或手动关闭
– 总结经验教训
## 6. 持续改进
– 分析告警原因
– 优化监控配置
– 预防类似问题再次发生
4.3.2 常见告警处理示例
## 1. TiDB实例宕机
– 告警:TiDBDown
– 级别:critical
– 处理步骤:
1. 登录TiDB服务器
2. 检查TiDB进程状态
3. 查看TiDB日志
4. 重启TiDB服务
5. 验证服务恢复
## 2. TiKV存储不足
– 告警:TiKVHighStorageUsage
– 级别:critical
– 处理步骤:
1. 登录TiKV服务器
2. 检查存储使用情况
3. 分析数据增长原因
4. 增加存储容量或清理数据
5. 验证存储使用恢复正常
## 3. PD集群不健康
– 告警:PDClusterUnhealthy
– 级别:critical
– 处理步骤:
1. 登录PD服务器
2. 检查PD进程状态
3. 查看PD日志
4. 检查集群状态
5. 修复PD服务
6. 验证集群恢复正常
## 4. TiDB高QPS
– 告警:TiDBHighQPS
– 级别:warning
– 处理步骤:
1. 登录监控系统
2. 查看QPS趋势
3. 分析SQL语句
4. 优化SQL或增加资源
5. 验证QPS恢复正常
Part05-风哥经验总结与分享
5.1 监控指标最佳实践
监控指标最佳实践:
- 选择关键指标:只监控对系统运行状态有重要影响的指标
- 设置合理的采集频率:根据指标的重要性和变化频率设置采集频率
- 建立基线:了解正常情况下的指标范围,便于识别异常
- 使用复合指标:结合多个指标进行分析,更全面地了解系统状态
- 定期 review 指标:根据系统变化和业务需求,定期调整监控指标
- 可视化指标:使用图表和仪表盘直观展示指标变化
- 保存历史数据:保留足够的历史数据,便于趋势分析和问题排查
5.2 告警配置技巧
告警配置技巧:
- 设置合理的阈值:根据系统实际情况设置告警阈值,避免误告警
- 使用适当的持续时间:设置合理的for子句,避免瞬时波动导致的误告警
- 配置告警抑制:避免同一问题产生多个告警,减少告警噪音
- 使用多个告警渠道:配置多种告警渠道,提高告警的可靠性
- 分级告警:根据问题的严重程度设置不同级别的告警
- 定期测试告警:定期测试告警系统,确保告警能够正常发送
- 优化告警信息:提供清晰、准确的告警信息,便于快速定位问题
5.3 常见问题处理
## 1. 告警风暴
– 现象:短时间内产生大量告警
– 原因:
– 系统故障导致多个指标异常
– 告警规则设置不当
– 网络中断导致多个目标不可达
– 解决方案:
– 配置告警抑制
– 调整告警规则
– 实施告警分组
– 优化网络架构
## 2. 误告警
– 现象:告警触发但实际系统正常
– 原因:
– 告警阈值设置不当
– 采集频率过低
– 网络波动导致指标异常
– 解决方案:
– 调整告警阈值
– 增加采集频率
– 设置合理的持续时间
– 优化网络稳定性
## 3. 告警延迟
– 现象:问题发生后很久才收到告警
– 原因:
– 采集频率过高
– 告警规则评估周期过长
– 告警通知渠道延迟
– 解决方案:
– 调整采集频率
– 缩短告警评估周期
– 优化告警通知渠道
– 配置多种告警渠道
## 4. 告警漏报
– 现象:系统出现问题但未收到告警
– 原因:
– 告警规则配置错误
– 监控目标不可达
– 告警渠道故障
– 解决方案:
– 检查告警规则配置
– 确保监控目标可达
– 测试告警通知渠道
– 配置冗余告警渠道
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
