告警和通知

Uptrace 提供了强大的告警和通知系统,帮助您及时发现和响应系统异常。通过配置监控器(Monitors)和通知渠道(Notification Channels),您可以基于指标(Metrics)和错误(Errors)创建告警规则,并通过多种渠道接收通知。

概述

告警系统是 Uptrace 平台的核心功能之一,它能够:

  • 实时监控:持续监控系统和应用的关键指标
  • 智能告警:基于阈值和条件自动触发告警
  • 多渠道通知:支持邮件、Slack、Telegram、PagerDuty 等多种通知方式
  • 告警抑制:通过自适应通知频率避免告警风暴
  • 历史追踪:记录所有告警历史,便于问题分析和复盘

告警系统架构

┌─────────────┐
│ Monitors │
│ ┌────────┐ │
│ │ Metric │ │
│ │ Monitor│ │
│ └───┬────┘ │
│ ┌───▼────┐ │
│ │ Error │ │
│ │ Monitor│ │
│ └───┬────┘ │
└───────┼─────┘
│
▼
┌─────────┐
│ Alerts │
└────┬────┘
│
▼
┌─────────────────┐
│ Notification │
│ Channels │
│ ┌─────────────┐ │
│ │ Email │ │
│ │ Slack │ │
│ │ Telegram │ │
│ │ PagerDuty │ │
│ │ Webhook │ │
│ └─────────────┘ │
└─────────────────┘

监控类型

Uptrace 支持两种类型的监控器:指标监控器(Metric Monitors)和错误监控器(Error Monitors)。

指标监控器(Metric Monitors)

指标监控器允许您基于指标值创建告警。当监控的指标值满足特定条件时,系统会自动触发告警。

工作原理

  1. 指标采集:Uptrace 持续采集系统和应用的指标数据
  2. 条件评估:根据配置的查询表达式和阈值评估指标值
  3. 告警触发:当条件满足时,创建告警并发送通知
  4. 告警恢复:当指标恢复正常时,自动关闭告警并发送恢复通知

配置方法

您可以通过两种方式创建指标监控器:

方式一:使用 UI 创建

  1. 登录 Uptrace 平台:https://uptrace.inner.youdao.com/
  2. 选择项目
  3. 导航到 "Alerting" → "Monitors"
  4. 点击 "New monitor" → "Metric monitor"
  5. 填写监控器配置信息
  6. 保存配置

方式二:使用 YAML 创建

  1. 导航到 "Alerting" → "Monitors"
  2. 点击 "New monitor" → "From YAML"
  3. 粘贴 YAML 配置
  4. 保存配置

监控系统指标示例

Uptrace 支持监控 OpenTelemetry 主机指标(Host Metrics)。以下是一些常用的监控示例:

监控 CPU 使用率

当 CPU 使用率超过 300% 时触发告警(在多核系统中,300% 表示 3 个核心 100% 使用):

metric_monitors:
- name: CPU usage
metrics:
- system_cpu_load_average_15m as $load_avg_15m
- system_cpu_time as $cpu_time
query:
- $load_avg_15m / uniq($cpu_time.cpu) as cpu_util
- group by host_name
column: cpu_util
column_unit: utilization
max_allowed_value: 3
check_num_point: 10

配置说明:

  • metrics:定义要监控的指标,使用别名便于后续引用
  • query:查询表达式,计算 CPU 使用率
    • $load_avg_15m:15 分钟平均负载
    • uniq($cpu_time.cpu):唯一 CPU 核心数
    • cpu_util:计算得到的 CPU 使用率
  • group by host_name:按主机名分组,为每台主机创建独立的告警
  • column: cpu_util:指定要监控的列
  • column_unit: utilization:指定单位为利用率(0-1 范围,但这里允许超过 1)
  • max_allowed_value: 3:最大允许值为 3(即 300%)
  • check_num_point: 10:需要连续 10 个数据点都超过阈值才触发告警
监控文件系统使用率

当文件系统使用率超过 90% 时触发告警:

metric_monitors:
- name: Filesystem usage
metrics:
- system_filesystem_usage as $fs_usage
query:
- $fs_usage{state='used'} / $fs_usage as fs_util
- group by host_name, mountpoint
- where mountpoint !~ "/snap"
column: fs_util
column_unit: utilization
max_allowed_value: 0.9
check_num_point: 3

配置说明:

  • $fs_usage{state='used'}:已使用的文件系统空间
  • $fs_usage:总文件系统空间
  • fs_util:计算使用率
  • group by host_name, mountpoint:按主机和挂载点分组
  • where mountpoint !~ "/snap":排除 /snap 挂载点(Snap 包管理器)
  • max_allowed_value: 0.9:最大允许使用率为 90%
  • check_num_point: 3:需要连续 3 个数据点超过阈值
监控磁盘待处理操作数

当磁盘待处理操作数超过 100 时触发告警:

metric_monitors:
- name: Disk pending operations
metrics:
- system_disk_pending_operations as $pending_ops
query:
- $pending_ops
- group by host_name, device
max_allowed_value: 100
check_num_point: 10

配置说明:

  • system_disk_pending_operations:磁盘待处理的 I/O 操作数
  • group by host_name, device:按主机和设备分组
  • max_allowed_value: 100:最大允许 100 个待处理操作
  • check_num_point: 10:需要连续 10 个数据点超过阈值
监控网络错误

当网络错误数大于 0 时立即触发告警:

metric_monitors:
- name: Network errors
metrics:
- system_network_errors as $net_errors
query:
- $net_errors
- group by host_name
max_allowed_value: 0
check_num_point: 3

配置说明:

  • system_network_errors:网络错误计数
  • max_allowed_value: 0:不允许任何网络错误
  • check_num_point: 3:需要连续 3 个数据点检测到错误

监控追踪数据示例

除了系统指标,您还可以监控追踪数据(Spans、Logs、Events)。Uptrace 提供了以下系统指标来访问追踪数据:

  • uptrace_tracing_spans:Span 数量和持续时间(不包括 events 和 logs)
  • uptrace_tracing_logs:日志数量(不包括 spans 和 events)
  • uptrace_tracing_events:事件数量(不包括 spans 和 logs)

您可以使用所有可用的 Span 属性进行过滤和分组,例如 where _status_code = 'error' 或 group by host_name。

监控 PostgreSQL SELECT 查询平均持续时间

当 PostgreSQL SELECT 查询的平均持续时间超过 10 毫秒时触发告警:

metric_monitors:
- name: PostgreSQL SELECT duration
metrics:
- uptrace_tracing_spans as $spans
query:
- avg($spans)
- where _system = 'db:postgresql'
- where db_operation = 'SELECT'
max_allowed_value: 10000 # 10 毫秒
check_num_point: 5

配置说明:

  • uptrace_tracing_spans:追踪中的 Span 数据
  • where _system = 'db:postgresql':过滤 PostgreSQL 数据库操作
  • where db_operation = 'SELECT':只监控 SELECT 查询
  • avg($spans):计算平均持续时间
  • max_allowed_value: 10000:最大允许 10 毫秒(单位:纳秒)
  • check_num_point: 5:需要连续 5 个数据点超过阈值
监控数据库操作中位数持续时间

监控所有数据库操作的中位数持续时间:

metric_monitors:
- name: Database operations duration
metrics:
- uptrace_tracing_spans as $spans
query:
- p50($spans)
- where _type = "db"
max_allowed_value: 10000 # 10 毫秒
check_num_point: 5

配置说明:

  • where _type = "db":过滤所有数据库操作
  • p50($spans):计算中位数(50 百分位数)持续时间
监控错误数量

当每分钟错误日志数量超过 10 条时触发告警:

metric_monitors:
- name: Number of errors
metrics:
- uptrace_tracing_logs as $logs
query:
- perMin(sum($logs))
- where _system in ("log:error", "log:fatal")
max_allowed_value: 10
check_num_point: 3

配置说明:

  • uptrace_tracing_logs:追踪中的日志数据
  • where _system in ("log:error", "log:fatal"):只监控 ERROR 和 FATAL 级别的日志
  • perMin(sum($logs)):计算每分钟的日志总数
  • max_allowed_value: 10:每分钟最多允许 10 条错误日志
监控失败请求

当每分钟失败请求数大于 0 时触发告警:

metric_monitors:
- name: Failed requests
metrics:
- uptrace_tracing_spans as $spans
query:
- perMin(count($spans{_status_code="error"})) as failed_requests
- where _type = "httpserver"
max_allowed_value: 0

配置说明:

  • $spans{_status_code="error"}:状态码为 error 的 Span
  • where _type = "httpserver":只监控 HTTP 服务器请求
  • perMin(count(...)):计算每分钟的失败请求数
  • max_allowed_value: 0:不允许任何失败请求

查询语法和表达式

指标监控器使用类似 PromQL 的查询语言,支持以下功能:

基本语法:

  • 指标别名:system_cpu_usage as $cpu_usage
  • 数学运算:$cpu_usage * 100
  • 聚合函数:avg(), sum(), min(), max(), p50(), p95(), p99()
  • 过滤条件:where condition
  • 分组:group by attribute1, attribute2
  • 时间函数:perMin(), perHour(), perDay()

常用表达式示例:

# 计算 CPU 使用率百分比
query:
- $cpu_time / uniq($cpu_time.cpu) * 100 as cpu_percent
# 计算错误率
query:
- sum($errors) / sum($requests) * 100 as error_rate
- where _type = "httpserver"
# 计算 P95 延迟
query:
- p95($duration)
- where service_name = "api-service"
# 按环境分组
query:
- avg($cpu_usage)
- group by deployment_environment

错误监控器(Error Monitors)

错误监控器允许您监控特定的错误(异常)和日志。Uptrace 会自动为 log_severity 级别为 ERROR 和 FATAL 的日志创建一个错误监控器。

自动错误监控

Uptrace 默认会监控所有 ERROR 和 FATAL 级别的日志:

  • 自动创建告警
  • 自动分组相似的错误
  • 自动发送通知(如果配置了通知渠道)

自定义错误过滤

您可以使用所有可用的过滤器来包含或排除要监控的日志。例如,使用 where display_name contains "timeout" 只监控包含 "timeout" 的错误。

您也可以自定义默认过滤器来监控其他日志级别,例如 _system in ("log:warn", "log:error", "log:fatal")。

错误分组和聚合

您可以添加 group by 子句来自定义默认的错误分组,并创建单独的告警/通知。例如,group by _group_id, service_name, cloud_region 会为每个服务、每个区域的每个错误组创建独立的告警。

错误监控器示例

监控所有错误

通知所有错误,按错误组分组:

error_monitors:
- name: Notify on all errors
notify_everyone_by_email: true
query:
- group by _group_id
- where _system in ("log:error", "log:fatal")

配置说明:

  • notify_everyone_by_email: true:通过邮件通知所有项目成员
  • group by _group_id:按错误组 ID 分组,相同错误只创建一个告警
  • where _system in ("log:error", "log:fatal"):只监控 ERROR 和 FATAL 级别
监控特定错误消息

只监控包含 "timeout" 的错误:

error_monitors:
- name: Notify on "timeout" errors
notify_everyone_by_email: true
query:
- group by _group_id
- where _system in ("log:error", "log:fatal")
- where display_name contains "timeout"

配置说明:

  • where display_name contains "timeout":只监控错误消息中包含 "timeout" 的错误
监控异常

监控所有包含异常类型的错误:

error_monitors:
- name: Exceptions
notify_everyone_by_email: true
query:
- group by _group_id
- where _system in ("log:error", "log:fatal")
- where exception_type exists

配置说明:

  • where exception_type exists:只监控包含异常类型的错误
监控特定环境外的错误

监控除 dev 环境外的所有错误:

error_monitors:
- name: Notify on all errors except in "dev" environment
notify_everyone_by_email: true
query:
- group by _group_id
- group by deployment_environment
- where _system in ("log:error", "log:fatal")
- where deployment_environment != "dev"

配置说明:

  • group by deployment_environment:按部署环境分组
  • where deployment_environment != "dev":排除开发环境

告警名称自定义

Uptrace 会自动生成告警名称,但您可以通过 Go 模板语法自定义告警名称。

指标监控器的告警名称

对于指标监控器,Uptrace 使用监控器名称和时间序列名称生成告警名称,例如:"Disk usage: myhost+mydisk"。

错误监控器的告警名称

对于错误监控器,Uptrace 使用错误(日志)消息生成告警名称,例如:"ERROR *fmt.wrapError: writeError failed"。

自定义告警名称

您可以在创建监控器时,将监控器名称指定为 Go 模板字符串来自定义告警名称。例如:

metric_monitors:
- name: '{{ .Attrs.deployment_environment_name }}: {{ .DisplayName }}'
# ... 其他配置

这个模板会在告警名称前添加部署环境名称。

模板变量

您可以在模板中使用以下变量:

变量类型描述
{{ .DisplayName }}String与查询 spans 和 logs 时的 _display_name 相同
{{ .Attrs }}map[string]any所有可用的属性,例如 {{ .Attrs.service_name }}

示例:

# 使用服务名和环境名作为前缀
metric_monitors:
- name: '{{ .Attrs.service_name }} ({{ .Attrs.deployment_environment }}): {{ .DisplayName }}'
# ... 其他配置
# 使用主机名
metric_monitors:
- name: '{{ .Attrs.host_name }} - {{ .DisplayName }}'
# ... 其他配置

通知渠道配置

通知渠道定义了告警通知的发送方式。Uptrace 支持多种通知渠道,您可以为每个监控器配置一个或多个通知渠道。

支持的渠道

Uptrace 支持以下通知渠道:

  • Email(邮件):发送告警邮件到指定邮箱
  • Slack:发送消息到 Slack 频道或用户
  • Telegram:发送消息到 Telegram 群组或用户
  • Microsoft Teams:发送消息到 Teams 频道
  • PagerDuty:集成 PagerDuty 事件管理
  • Opsgenie:集成 Opsgenie 告警管理
  • AlertManager:集成 Prometheus AlertManager
  • Webhook:发送 HTTP POST 请求到自定义 Webhook

创建通知渠道

创建通知渠道的步骤:

  1. 登录 Uptrace 平台
  2. 导航到 "Alerting" → "Channels"
  3. 点击 "New channel"
  4. 选择渠道类型(例如 "Slack")
  5. 填写配置信息
  6. 保存配置

渠道条件配置

在创建通知渠道时,您可以指定条件来过滤通知。只有满足条件的告警才会通过该渠道发送。

Uptrace 使用 Expr 语言编写条件。除了 Expr 内置函数外,Uptrace 还支持以下函数:

函数说明
monitorName() string返回监控器名称
alertName() string返回告警名称
alertType() string返回告警类型:error 或 metric
attr(key string) string返回告警属性值
hasAttr(key string) bool如果告警属性存在则返回 true

条件示例

只发送生产环境的通知:

attr("deployment_environment") == "prod"

只发送主机名以 prod- 开头的通知:

attr("host_name") startsWith "prod-"

只发送监控器名称包含 "URGENT" 的通知:

monitorName() contains "URGENT"

组合条件:

attr("deployment_environment") == "prod" && alertType() == "metric"

通知频率控制

为了避免告警风暴,Uptrace 使用自适应通知频率机制。通知频率会根据告警持续时间自动调整。

指标监控器的通知频率

  • 初始间隔:15 分钟
  • 递增规则:每 3 次通知后,间隔时间翻倍
  • 间隔序列:15m, 15m, 15m, 30m, 30m, 30m, 1h, 1h, 1h, 2h, 2h, 2h, 4h, 4h, 4h...
  • 最大间隔:24 小时

错误监控器的通知频率

  • 初始间隔:1 小时
  • 递增规则:每 2 次通知后,间隔时间翻倍
  • 间隔序列:1h, 1h, 2h, 2h, 4h, 4h, 8h, 8h, 16h, 16h...
  • 最大间隔:1 周

告警恢复通知

当告警关闭(指标恢复正常或错误停止)时,Uptrace 会立即发送恢复通知,不受通知频率限制。

通知总数

通知总数不受限制。例如,如果指标监控器从未恢复,您将每 24 小时收到一次通知,持续无限期。

邮件通知配置

邮件通知是 Uptrace 社区版支持的基础通知方式。要接收邮件通知,需要确保:

  1. 用户邮箱正确:用户账户中配置了正确的邮箱地址
  2. 邮件服务配置:Uptrace 服务器配置了邮件服务(SMTP)
  3. 邮件服务启用:邮件服务已启用并正常工作

配置邮件服务(自托管版本)

如果您使用的是自托管版本的 Uptrace,需要在配置文件中设置邮件服务:

# uptrace.yml
mailer:
enabled: true
smtp:
addr: smtp.example.com:587
username: your-email@example.com
password: your-password
from: uptrace@example.com

使用邮件通知

在创建监控器时,可以设置 notify_everyone_by_email: true 来通过邮件通知所有项目成员:

error_monitors:
- name: Critical errors
notify_everyone_by_email: true
query:
- group by _group_id
- where _system in ("log:error", "log:fatal")

实战示例

示例 1:完整的系统监控告警配置

创建一个完整的系统监控告警配置,监控 CPU、内存、磁盘和网络:

metric_monitors:
# CPU 使用率监控
- name: High CPU usage
metrics:
- system_cpu_load_average_15m as $load_avg_15m
- system_cpu_time as $cpu_time
query:
- $load_avg_15m / uniq($cpu_time.cpu) as cpu_util
- group by host_name
column: cpu_util
column_unit: utilization
max_allowed_value: 3
check_num_point: 10
notify_channels:
- email
- slack
# 内存使用率监控
- name: High memory usage
metrics:
- system_memory_utilization as $mem_util
query:
- avg($mem_util)
- group by host_name
column: mem_util
column_unit: utilization
max_allowed_value: 0.9
check_num_point: 5
notify_channels:
- email
- slack
# 磁盘使用率监控
- name: High disk usage
metrics:
- system_filesystem_usage as $fs_usage
query:
- $fs_usage{state='used'} / $fs_usage as fs_util
- group by host_name, mountpoint
- where mountpoint !~ "/snap"
column: fs_util
column_unit: utilization
max_allowed_value: 0.9
check_num_point: 3
notify_channels:
- email
- slack
# 网络错误监控
- name: Network errors
metrics:
- system_network_errors as $net_errors
query:
- $net_errors
- group by host_name
max_allowed_value: 0
check_num_point: 3
notify_channels:
- email
- slack
- pagerduty

示例 2:应用性能监控告警

监控应用的关键性能指标:

metric_monitors:
# 高错误率监控
- name: High error rate
metrics:
- uptrace_tracing_spans as $spans
query:
- perMin(count($spans{_status_code="error"})) / perMin(count($spans)) as error_rate
- where _type = "httpserver"
- group by service_name
column: error_rate
column_unit: utilization
max_allowed_value: 0.05 # 5% 错误率
check_num_point: 5
notify_channels:
- email
- slack
# 慢请求监控
- name: Slow requests
metrics:
- uptrace_tracing_spans as $spans
query:
- p95($spans)
- where _type = "httpserver"
- group by service_name, span_name
max_allowed_value: 1000000000 # 1 秒
check_num_point: 5
notify_channels:
- email
# 数据库慢查询监控
- name: Slow database queries
metrics:
- uptrace_tracing_spans as $spans
query:
- p95($spans)
- where _type = "db"
- group by db_system, db_operation
max_allowed_value: 500000000 # 500 毫秒
check_num_point: 5
notify_channels:
- email
- slack

示例 3:错误监控配置

配置全面的错误监控:

error_monitors:
# 所有错误(生产环境)
- name: All errors in production
notify_everyone_by_email: true
query:
- group by _group_id
- group by service_name
- where _system in ("log:error", "log:fatal")
- where deployment_environment == "production"
notify_channels:
- email
- slack
- pagerduty
# 超时错误
- name: Timeout errors
notify_everyone_by_email: true
query:
- group by _group_id
- where _system in ("log:error", "log:fatal")
- where display_name contains "timeout"
notify_channels:
- email
- slack
# 数据库连接错误
- name: Database connection errors
notify_everyone_by_email: true
query:
- group by _group_id
- where _system in ("log:error", "log:fatal")
- where display_name contains "database" || display_name contains "connection"
notify_channels:
- email
- pagerduty

示例 4:使用渠道条件过滤通知

为不同严重程度的告警配置不同的通知渠道:

# 创建通知渠道
notification_channels:
# 紧急告警渠道(PagerDuty)
- name: Urgent alerts
type: pagerduty
condition: |
monitorName() contains "URGENT" ||
attr("deployment_environment") == "production" && alertType() == "error"
# 一般告警渠道(Slack)
- name: General alerts
type: slack
condition: |
attr("deployment_environment") != "dev" &&
!(monitorName() contains "URGENT")
# 开发环境告警渠道(邮件)
- name: Dev alerts
type: email
condition: attr("deployment_environment") == "dev"

最佳实践

告警规则设计原则

  1. 明确告警目标:每个告警应该有明确的业务价值,避免创建无意义的告警
  2. 合理设置阈值:阈值应该基于历史数据和业务需求,避免过于敏感或过于宽松
  3. 使用合适的检查点数:check_num_point 应该根据指标的波动性设置,避免误报
  4. 分组策略:合理使用 group by,避免创建过多告警

避免告警风暴

  1. 利用自适应通知频率:Uptrace 的自适应通知频率机制可以有效减少告警风暴
  2. 使用渠道条件:通过条件过滤,只为重要告警发送通知
  3. 合并相似告警:使用 group by 将相似的告警合并
  4. 设置告警抑制:对于已知问题,可以临时禁用相关告警

告警阈值设置建议

系统指标阈值建议:

  • CPU 使用率:80-90%(根据服务器类型调整)
  • 内存使用率:85-90%
  • 磁盘使用率:85-90%
  • 磁盘 I/O 等待:> 50ms
  • 网络错误:0(不允许任何错误)

应用指标阈值建议:

  • 错误率:< 1%(关键服务),< 5%(一般服务)
  • P95 延迟:< 500ms(API 服务),< 100ms(内部服务)
  • 请求量下降:> 20%(可能表示服务异常)

告警命名规范

建议使用统一的告警命名规范:

[环境]-[服务/组件]-[指标类型]-[阈值]

例如:

  • prod-api-error-rate-5%
  • prod-db-query-duration-500ms
  • prod-cpu-usage-80%

通知渠道选择

根据告警严重程度选择通知渠道:

  • 紧急告警:PagerDuty、电话、短信
  • 重要告警:Slack、Teams、邮件
  • 一般告警:邮件、Slack
  • 信息性告警:仅记录,不发送通知

定期审查告警规则

  1. 定期审查:每月审查一次告警规则,删除不再需要的规则
  2. 分析告警历史:分析告警历史,识别误报和漏报
  3. 优化阈值:根据实际运行情况调整阈值
  4. 文档化:为每个告警规则编写文档,说明告警原因和处理方法

常见问题

1. 告警没有触发?

可能的原因:

  • 检查监控器配置:确认监控器已启用且配置正确
  • 检查指标数据:确认指标数据正在被采集
  • 检查阈值设置:确认阈值设置合理,不是过于严格
  • 检查检查点数:确认 check_num_point 设置合理
  • 查看告警历史:查看是否有相关的告警记录

2. 收到太多告警通知?

解决方法:

  • 调整阈值:提高阈值,减少告警频率
  • 增加检查点数:增加 check_num_point,减少误报
  • 使用渠道条件:通过条件过滤,只为重要告警发送通知
  • 利用自适应频率:Uptrace 会自动减少重复告警的通知频率

3. 如何测试告警配置?

测试方法:

  1. 创建测试监控器:创建一个测试监控器,设置较低的阈值
  2. 触发测试告警:手动触发一个测试告警(例如,临时修改阈值)
  3. 验证通知:确认通知已发送到所有配置的渠道
  4. 清理测试数据:测试完成后,删除或禁用测试监控器

4. 如何查看告警历史?

查看方法:

  1. 登录 Uptrace 平台
  2. 导航到 "Alerting" → "Alerts"
  3. 查看所有告警历史记录
  4. 可以按时间、状态、监控器类型等过滤

5. 如何自定义告警通知内容?

Uptrace 目前不支持完全自定义通知内容,但您可以通过以下方式影响通知内容:

  • 自定义告警名称:使用 Go 模板自定义告警名称
  • 使用 Webhook:通过 Webhook 接收告警,然后自定义处理逻辑
  • 集成第三方系统:将告警发送到支持自定义模板的第三方系统(如 PagerDuty)

6. 告警恢复通知没有发送?

可能的原因:

  • 检查通知渠道配置:确认通知渠道已正确配置
  • 检查告警状态:确认告警确实已恢复
  • 查看通知历史:查看是否有恢复通知的记录

7. 如何为不同环境设置不同的告警规则?

方法:

  1. 使用环境过滤:在查询中使用 where deployment_environment == "production" 过滤
  2. 创建环境特定的监控器:为每个环境创建独立的监控器
  3. 使用渠道条件:通过渠道条件为不同环境配置不同的通知方式

下一步

参考资源

在Gitlab上编辑本文档