十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Grafana Tempo Metrics-generator 全面解析:从 Trace 派生指标、处理器架构与 remote write 实战指南

Grafana Tempo Metrics-generator 全面解析:从 Trace 派生指标、处理器架构与 remote write 实战指南 后端可观测性链路追踪【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址https://gitcode.com/GitHub_Trending/tempo1/tempo点击查看免费下载导读Metrics-generator 是 Grafana Tempo 中一个可选的独立组件负责从已接入的 Trace 数据中派生 Prometheus 指标Span Metrics、Service Graphs、Host Info并通过 Prometheus remote write 协议写往 Prometheus 或 Grafana Mimir 等指标后端。本文以官方文档 docs/sources/tempo/metrics-from-traces/metrics-generator/_index.md 为骨架结合仓库内的配置参考与源码实现系统讲解其架构、三大处理器、remote write 配置、原生直方图、多租户支持以及滚动发布时的分区交接机制读完即可在 Tempo 中独立启用并调优 metrics-generator。一、Metrics-generator 是什么Metrics-generator 是 Tempo 的可选组件核心职责是从已接入的 Trace 中派生指标。它从 Kafka 消费 Trace 数据内部运行一组处理器processors每个处理器消费 Span 并产出各自的指标最终通过 Prometheusremote write 协议将指标写入 Prometheus 数据源或任意 Prometheus 兼容端点。在 参考架构文档 中其数据接入方式取决于部署模式微服务模式metrics-generator 作为独立消费组直接从 Kafka 消费 Trace 数据与 live-store、block-builder 并列并独立维护自己的消费偏移。单二进制monolithic模式metrics-generator 在进程内直接从 distributor 接收 Trace 数据不涉及 Kafka 消费。从仓库源码看该组件定义于 modules/generator 目录下其中 config.go 定义了完整配置结构ring、processor、registry、storage等子块并默认ConsumeFromKafka由部署模型在 app 初始化时决定属于内部接线而非用户可配置项。采样前置条件如果在 Trace 到达 Tempo 之前就进行了采样指标生成的位置取决于采样方式。完整决策树见 选择在何处从 Trace 生成指标若 Trace 未采样到达 Tempo建议使用 metrics-generator若在 collector 侧做了 tail sampling则应在 Alloy / OpenTelemetry Collector 中生成指标避免指标只描述采样后的样本而非真实流量。二、整体架构与数据处理链路Metrics-generator 的数据链路如下被插桩的应用将 Trace 发送给distributordistributor 将数据写入Kafka微服务模式metrics-generator从 Kafka 消费 Trace 数据依次送入已配置的处理器span metrics、service graphs、host info每个处理器派生不同的指标集metrics-generator 将指标通过 remote write 写往 Prometheus 兼容后端如 Prometheus、Grafana Mimir。当前可用的处理器包括处理器产出内容Service graphs服务间调用关系图请求数、失败数、时延等边指标Span metrics基于单个 Span 的 RED 指标请求率、错误率、时延Host info基于资源属性的traces_host_infogauge 指标注意Tempo 3.0 变更Tempo 3.0 移除了local-blocks处理器。如果配置中仍有metrics_generator.processors中的local-blocks条目请移除。近期数据的 TraceQL 指标查询由 live-store 组件负责。2.1 Service graphs 处理器Service graphs 是分布式系统中服务间关系的可视化表示。该处理器通过分析 Trace 构建服务地图目标是发现边edges——即具有父子关系的 Span代表两个服务之间的一次跳转例如一次请求。处理器将请求计数与耗时记录为指标用它们来表示整张图。处理器会识别以下类型的请求依据 OpenTelemetry 语义约定直接请求出站 Span 的span.kind为client入站 Span 的span.kind为server跨消息系统的请求出站与入站 Span 的span.kind分别为producer与consumer数据库请求Span 包含span.kindclient且带有db.namespace、db.name、db.system或db.system.name之一可通过database_name_attributes配置自定义识别属性。处理器将每个能形成请求对的 Span 保存在内存 store 中直到匹配的成对 Span 到达或超过最大等待时间wait默认 10s任一条件满足即记录该请求并将其从本地 store 中移除。每个指标序列带有client与server标签分别对应发起方与接收方服务traces_service_graph_request_total{clientapp, serverdb, connection_typedatabase} 20虚拟节点virtual nodes当请求对的一端未被采集外部系统未插桩或超出用户可达范围时处理器通过两种方式识别虚拟节点未插桩客户端缺少 client Span根 Span 的span.kind为server或consumer且无匹配的 client Span。Tempo metrics-generator 会先检查 server Span 上配置的peer_attributes默认[peer.service, db.name, db.system, db.system.name]命中则用其值作为客户端节点名否则默认user未插桩服务端缺少 server Spanclient Span 无匹配 server Span 但带有 peer 属性此时用该 peer 属性值作为虚拟服务端节点名按顺序取第一个匹配项。connection_type的可能取值为unset、virtual_node、messaging_system、database。子处理器subprocessors可在 overrides 中按指标类别单独启用处理器名称常量定义于 modules/generator/processor/processor_names.goservice-graphs-request仅产出traces_service_graph_request_total与traces_service_graph_request_failed_total计数器service-graphs-latency仅产出traces_service_graph_request_server_seconds与traces_service_graph_request_client_seconds直方图traces_service_graph_request_messaging_system_seconds还需在 metrics-generator 配置中开启enable_messaging_system_latency_histogram: trueservice-graphs-connection-info仅产出traces_service_graph_connection_infogauge默认关闭必须显式列出才会启用。裸名称service-graphs会启用 request 与 latency 两类指标将service-graphs-connection-info与裸名称并列列出是加性生效不会关闭 RED 指标而将service-graphs-request或service-graphs-latency与裸名称并列则是冗余的会被静默丢弃。示例overrides: defaults: metrics_generator: processors: - service-graphs - service-graphs-connection-infoService graphs 导出的指标指标类型标签说明traces_service_graph_request_totalCounterclient, server, connection_type两个节点之间的请求总数traces_service_graph_request_failed_totalCounterclient, server, connection_type两个节点之间的失败请求总数traces_service_graph_request_server_secondsHistogramclient, server, connection_type从服务端视角观察的请求耗时traces_service_graph_request_client_secondsHistogramclient, server, connection_type从客户端视角观察的请求耗时traces_service_graph_request_messaging_system_secondsHistogramclient, server, connection_type默认关闭消息系统中发布与消费之间的耗时traces_service_graph_connection_infoGaugeclient, server, connection_type默认关闭服务间边的存在性信号每条活跃边取值 1traces_service_graph_unpaired_spans_totalCounterclient, server, connection_type未配对的 Span 总数traces_service_graph_dropped_spans_totalCounterclient, server, connection_type被丢弃的 Span 总数其中traces_service_graph_connection_info是仅在边被观测期间保持为 1 的存在性gauge用于拓扑发现而非速率计算——单个被观测的 Span 即可让该 gauge 保持存在因此在低流量端点或激进 head sampling 下rate(...)为零或噪声很大时服务间关系依然可见。可配合长窗口查询last_over_time(traces_service_graph_connection_info[1h]) 0可选标签virtual_node取值unset/client/server可通过enable_virtual_node_label: true开启显式标明未插桩的一侧。额外标签可通过dimensions配置加入标签经 Prometheus 名称转换后允许重复例如deployment.environment与deployment_environment可同时配置冲突时以最后配置的值为准。关键约束service graph 处理器必须处理一条 Trace 的两端 Span 才能正确配对。如果一条 Trace 的 Span 分散在多个实例上处理器无法可靠配对——因此它需要处理整条 Trace 的所有 Span。2.2 Span metrics 处理器Span metrics 处理器从 Span 派生 REDRequest、Error、Duration指标对每个唯一维度组合计算 Span 的总数与耗时。维度可以是服务名、操作名、Span kind、状态码以及 Span 中出现的任意标签或属性启用的维度越多生成指标的基数cardinality越高。Span metrics 处理器导出三个核心指标指标类型说明traces_spanmetrics_calls_totalCounterSpan 总数请求量traces_spanmetrics_latencyHistogramSpan 耗时的分布traces_spanmetrics_size_totalCounter接入 Span 的总大小默认情况下每个指标自带以下标签service、span_name、span_kind、status_code。status_message、job、instance为可选标签需要额外配置service产生 Span 的服务名span_nameSpan 的名称span_kindSpan 类型SPAN_KIND_SERVER/SPAN_KIND_CLIENT/SPAN_KIND_INTERNAL/SPAN_KIND_PRODUCER/SPAN_KIND_CONSUMERstatus_codeSpan 结果STATUS_CODE_UNSET/STATUS_CODE_OK/STATUS_CODE_ERRORstatus_message可选说明status_code原因的消息默认关闭可能含任意字符串基数极高jobenable_target_info: true时加入instanceenable_target_info: true且enable_instance_label: true时加入。禁用固有维度intrinsic dimensions通过intrinsic_dimensions配置可关闭默认标签以降低基数例如metrics_generator: processor: span_metrics: intrinsic_dimensions: service: true span_name: true span_kind: false # 关闭 span_kind 标签 status_code: true status_message: false # 默认关闭自定义维度与维度映射dimensions用于以默认净化后名称将 Span 属性加为标签dimension_mappings则用于重命名属性或组合多个属性为一个复合标签其source_labels必须使用原始属性名带点号name中的点号与下划线最终都会转换为下划线。示例dimension_mappings: - name: env source_labels: [deployment.environment] - name: service_instance source_labels: [service.name, service.namespace, service.version] join: /若 Span 属性service.nameabc、service.namespacedef、service.versionghi则结果为service_instanceabc/def/ghi。当自定义维度与默认标签冲突如status_code时该维度标签会被加上双下划线前缀__status_code。处理已采样 Trace若使用比例采样器可通过两种方式防止指标信息丢失方式一自定义 Span 属性采样器将采样比例写入X-SampleRatio属性并设置metrics_generator.processor.span_metrics.span_multiplier_key: X-SampleRatio处理器会取该值的倒数放大计数方式二tracestate 阈值若采样器按 OpenTelemetry probability sampling threshold 将概率写入 W3C tracestate 的otth:hex子键可开启enable_tracestate_span_multiplier: true自动提取倍数且 tracestate 阈值优先于span_multiplier_key当 tracestate 缺失或无效时回退到属性方式。过滤策略filter_policies支持include全部匹配逻辑 AND、include_any任一匹配即包含逻辑 OR与exclude匹配即拒绝优先于 include。使用作用域键区分资源与 Span 属性如resource.service.name、span.http.route内建键为name、status、kind属性值类型支持bool、double、int、string。示例排除shop-backend服务的 Spanmetrics_generator: processor: service_graphs: filter_policies: - exclude: match_type: strict attributes: - key: resource.service.name value: shop-backend2.3 Host info 处理器Host info 处理器从接入 Span 的资源属性派生一个traces_host_infogauge 指标。它使用可配置的标识符默认k8s.node.name与host.id识别发送 Trace 的主机并产出grafana_host_id与host_source标签。该处理器用于将 Trace 数据与主机级基础设施指标关联分析。配置项见 modules/generator/config.go 的ProcessorConfig校验逻辑metrics_generator: processor: host_info: # 用于推导唯一主机标识的资源属性 [host_identifiers: list of string | default [k8s.node.name, host.id]] # 生成的指标名 [metric_name: string | default traces_host_info]三、Remote write把指标写到 Prometheus 兼容后端metrics-generator 内部运行一个Prometheus Agent周期性将指标发送到remote_write端点。该端点可配置为任意 Prometheus 兼容端点。3.1 核心配置块以下为 配置参考 中 metrics-generator 的关键配置项# Metrics-generator 配置块 metrics_generator: # Ring 配置微服务模式多实例协同 ring: kvstore: KVStore config [store: string | default memberlist] [prefix: string | default collectors/] [heartbeat_period: duration | default 5s] [heartbeat_timeout: duration | default 1m] [instance_id: string | default os.Hostname()] [instance_interface_names: list of string | default [eth0, en0]] # Registry 配置 registry: # 采集指标并 remote write 的间隔 [collection_interval: duration | default 15s] # 超过该间隔未更新的序列视为陈旧并从 registry 删除控制活跃序列数 [stale_duration: duration | default 15m] # 追加到所有生成指标上的标签 [external_labels: map] # 若设置租户 ID 将作为指定名称的标签注入所有指标 [inject_tenant_id_as: string] # 标签名最大长度超出截断 [max_label_name_length: int | default 1024] # 标签值最大长度超出截断 [max_label_value_length: int | default 2048] # 用于控制 metrics-generator 内存的限流器类型series默认或 entity [limiter_type: string | default series] # ring 模式partition默认分区 ring或 generator遗留 generator ring [ring_mode: string | default partition] # Kafka 消费解码器push-bytes默认或 otlp [codec: string | default push-bytes] # 并发 Kafka 消费者数 [ingest_concurrency: uint | default 16] # metrics-generator Kafka 客户端使用的实例 ID [instance_id: string | default hostname] # Storage 与 remote write 配置 storage: # WAL 存储路径每个租户使用独立子目录 path: string # Prometheus Agent WAL 配置 wal: prometheus agent WAL config # 关闭时冲刷样本的等待时间 [remote_write_flush_deadline: duration | default 1m] # 是否在 remote write 请求中附加 X-Scope-OrgID 头 [remote_write_add_org_id_header: bool | default true] # remote write 端点列表Prometheus remote write 配置格式 remote_write: [- Prometheus remote write config] # 仅允许 end time 落在该时长范围内的 Span 参与指标生成 # 用于过滤过期的 Span即超过该时长的 Span 被丢弃 [metrics_ingestion_time_range_slack: duration | default 30s] # 启动时跳过陈旧积压各分区直接 seek 到 (now - slack) 而非回放已提交偏移 [skip_stale_backlog_on_startup: bool | default false]其中registry.collection_interval默认 15s即控制 remote write 的写入间隔metrics_ingestion_time_range_slack默认 30s保证只对新鲜的 Span 生成指标避免陈旧 Span 污染指标。3.2 敏感头部与多租户转发敏感头部安全在remote_write端点的headersmap 中配置的值会以明文形式出现在/status/config端点返回的配置中可能泄露认证令牌。应改用http_headers并配合secrets字段Tempo 会将这些值掩码为secretmetrics_generator: storage: remote_write: - url: https://prometheus.example.com/api/v1/write http_headers: # 显示配置中被掩码为 secret X-Custom-Token: secrets: - SECRET_VALUE # 明文存储与显示 X-Custom-Header: values: - plaintext-value # 从磁盘文件读取头部值 X-From-File: files: - /path/to/token多租户转发启用多租户时metrics-generator 默认将原始请求的X-Scope-OrgID头转发到remote_write端点。如需禁用此行为设置remote_write_add_org_id_header: false默认true。3.3 按租户的 overrides 配置metrics-generator 的处理器默认关闭需在 overrides 中为指定租户启用。以下是 overrides 参考 中metrics_generator相关项overrides: defaults: metrics_generator: # 支持的处理器 # - service-graphs # - service-graphs-request 仅产出 request_total 与 request_failed_total # - service-graphs-latency 仅产出 request_server_seconds / request_client_seconds 直方图 # - service-graphs-connection-info 仅产出 connection_info显式启用 # - span-metrics # - span-metrics-count 仅产出 calls_total # - span-metrics-latency 仅产出 latency 直方图 # - span-metrics-size 仅产出 size_total # - host-info [processors: list of strings] # 每个 metrics-generator 实例的最大活跃序列数0 不限制 # 到达上限后不再新增序列但已有序列继续更新。 # 观测指标tempo_metrics_generator_registry_series_limited_total [max_active_series: int] # 最大活跃实体数唯一标签组合仅 limiter_typeentity 时生效 [max_active_entities: int] # 单个标签允许的最大不同值数超出后新值替换为 __cardinality_overflow__ [max_cardinality_per_label: uint64 | default 0] # 按租户的采集间隔0 表示使用全局默认 [collection_interval: duration] # 停止收集与导出样本仍摄入 Span 并更新内部计数用于估算活跃序列数 [disable_collection: bool | default false] # 生成指标中 exemplar 的 trace ID 标签名 [trace_id_label_name: string | default traceID] # span metrics 与 service graphs 的直方图实现classic / native / both [generate_native_histograms: classic|native|both | default classic] # 使用 DRAIN 聚类净化 span 名称以降基数关闭/ dry_run / enabled [span_name_sanitization: string | default ] # 发往指标后端的 per-tenant remote write 头部 [remote_write_headers: map of string to string] # 原生直方图桶增长因子仅 native/both 时生效 [native_histogram_bucket_factor: float | default 1.1] # 原生直方图最大桶数 [native_histogram_max_bucket_number: int | default 100] # 原生直方图计数器重置的最小间隔 [native_histogram_min_reset_duration: duration | default 15m]监控消费与写健康可用 参考架构文档 中的指标验证tempo_ingest_group_partition_lag{groupmetrics-generator} tempo_ingest_group_partition_lag_seconds{groupmetrics-generator} prometheus_remote_storage_samples_failed_total prometheus_remote_storage_samples_dropped_totallag 持续增大说明生成器处理落后tempo_ingest_storage_reader系列指标提供 Kafka 客户端 fetch 操作与错误的详细信息。四、原生直方图Native histograms原生直方图是 Prometheus 的一种数据类型可以生成、存储与查询高分辨率的观测直方图通常比经典直方图具有更高分辨率且插桩更直接。metrics-generator 支持为高分辨率数据产出原生直方图。启用后需要更新接收端点让接收端如 Mimir开启原生直方图摄入ingestion更新仪表盘查询将直方图查询升级为原生直方图查询方式。在 overrides 中通过generate_native_histograms选择模式classic默认 /native/both并可用native_histogram_bucket_factor默认 1.1、native_histogram_max_bucket_number默认 100、native_histogram_min_reset_duration默认 15m调节桶行为。从源码看该选项通过 modules/generator/config.go 中的copyWithOverrides将 per-tenant 的HistogramOverride同时应用到 service graphs 与 span metrics 两个处理器底层由 modules/generator/registry/native_histogram.go 与registry.go中的hasNativeHistograms判断实现。五、多租户支持Multitenancymetrics-generator 通过环境变量与 per-tenant overrides 支持多租户将多租户隔离传播到指标后端保持数据分离与安全。详细说明见 多租户支持文档。使用方式为每个租户定义remote_write_headersoverride配置文件中的环境变量在运行时展开需要给 Tempo 传递--config.expand-env标志。overrides: defaults: metrics_generator: processors: [ span-metrics ] team-traces-a: metrics_generator: remote_write_headers: Authorization: ${PROM_A_BASIC_AUTH} team-traces-b: metrics_generator: processors: [ span-metrics, service-graphs ] remote_write_headers: Authorization: ${PROM_B_BEARER_AUTH}export PROM_A_BASIC_AUTHBasic $(echo team-a:$(cat /token-prometheus-a)|base64|tr -d [:space:]) export PROM_B_BEARER_AUTHBearer $(cat /token-prometheus-b)要点PROM_A_BASIC_AUTH、PROM_B_BEARER_AUTH为环境变量存放各租户的授权令牌用于认证发往 Prometheus remote write 端点的请求因为remote_write_headers是 override其值会出现在/status/runtime_config端点中Tempo 会掩码为secret而不会出现在/status/config该端点排除 per-tenant overrides若直接在metrics_generator.storage.remote_write块中配置头部不要用headersmap 存放敏感值会在/status/config明文暴露应改用http_headers配合secrets。Tempo 3.0 提示Tempo 3.0 默认禁用遗留的扁平unscopedoverrides 格式。若现有 overrides 使用遗留格式请迁移到上文所示的 scoped 格式或临时设置enable_legacy_overrides: true。六、滚动发布时的分区交接Partition handoffmetrics-generator 使用 Kafka静态成员static membershipinstance_id使重启后具有相同身份的 Pod 能立即重新加入消费组无需等待 session timeout并重新认领先前持有的分区。这是StatefulSet部署的正确行为——Pod 名称在重启间保持稳定如metrics-generator-0。而对于Deployment部署每次重启 Pod 名称都会变化如metrics-generator-7f9d4b6c5-xk2pj。由于新 Pod 名称不同它会注册为新的静态成员旧成员槽位在 session timeout 到期前一直持有分区通常为几分钟。在这段时间窗口内这些分区处于空闲状态对应 Trace 数据不会生成任何指标。解决方案在 metrics-generator 上设置leave_consumer_group_on_shutdown: true。启用后正在关闭的 Pod 会在关闭前显式向 Kafka 协调器发送LeaveGroup请求协调器即可立即将分区重新分配给新 Pod而不必等待 session timeoutmetrics_generator: leave_consumer_group_on_shutdown: true # 推荐用于 Deployment 滚动发布反向建议StatefulSet 部署保持默认值leave_consumer_group_on_shutdown: false。因为instance_id稳定时关闭时发送LeaveGroup会导致每次重启都触发一次不必要的 leave-and-rejoin 再平衡短暂中断同一消费组内所有租户的指标生成。版本要求leave_consumer_group_on_shutdown需要Kafka 2.4 及以上版本——Kafka 2.4 通过 KIP-345 在LeaveGroup请求中引入了 per-member 的InstanceID字段。从源码看该配置定义于 modules/generator/config.go默认false并注明建议在 Deployment 部署Pod 名随机变化时设为 true以避免分区重新分配受 session timeout 延迟。其实际行为在 modules/generator/generator_kafka.go 的stopKafka中实现当开启该选项且InstanceID非空时关闭流程会调用leaveGroupFn按实例 ID 显式退出消费组并在失败时记录告警日志。七、Grafana Cloud 与成本提示如需在 Grafana Cloud 账户中启用 metrics-generator请查阅 Grafana Cloud 的 Metrics-generator 文档。启用指标生成并将其 remote write 到 Grafana Cloud Metrics 会产生额外的活跃序列active series可能影响账单计费。成本优化建议避免同时运行 collector 侧生成器与 Tempo metrics-generator 两条路径——两者互不替代各自写入自己的序列会导致活跃序列、计算量与成本翻倍。若已同时运行可在指标后端检查是否存在两套 span metrics / service graph 序列然后禁用其中一条路径关闭 Tempo 的 metrics-generator 处理器或移除 collector 管道中的 span metrics / service graph connector。八、配置速查与进阶阅读以下为本主题相关的最短可运行配置骨架单二进制部署启用 span metrics 并写往 Prometheusmetrics_generator: storage: path: /tmp/tempo/metrics-generator remote_write: - url: http://prometheus:9090/api/v1/write registry: collection_interval: 15s stale_duration: 15m overrides: defaults: metrics_generator: processors: [span-metrics, service-graphs, host-info]进一步阅读仓库内相关文档架构与部署模式reference-tempo-architecture/components/metrics-generator.md完整配置参考configuration/_index.mdmetrics-generator 与 overrides 两节采样与生成位置选择where-to-generate-metrics.mdService graphs 深入service_graphs/_index.mdSpan metrics 深入span-metrics/span-metrics-metrics-generator.md基数治理metrics-generator/cardinality.md、metrics-generator/active-series.md多租户metrics-generator/multitenancy.md故障排查troubleshooting/metrics-generator.md核心源码入口配置结构与默认值modules/generator/config.goKafka 消费与 LeaveGroup 实现modules/generator/generator_kafka.go处理器名称常量modules/generator/processor/processor_names.go原生直方图实现modules/generator/registry/native_histogram.go赞分享后端可观测性链路追踪【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址https://gitcode.com/GitHub_Trending/tempo1/tempo点击查看免费下载相关推荐Grafana Tempo Metrics-generator 架构解析从 Trace 派生指标、Kafka 消费与系列限制机制Grafana Tempo Metrics generator 架构解析从 Trace 派生指标、Kafka 消费与系列限制机制 metrics genera后端可观测性链路追踪Grafana Tempo 从追踪生成指标Metrics from traces实战指南metrics-generator 与 TraceQL metrics 全解析Grafana Tempo 从追踪生成指标Metrics from traces实战指南metrics generator 与 TraceQL metri后端可观测性链路追踪Grafana Tempo 使用 metrics-generator 从 Span 生成指标span metrics 处理器完整指南Grafana Tempo 使用 metrics generator 从 Span 生成指标span metrics 处理器完整指南 Part of the后端可观测性链路追踪上一篇Gopeed 完整上手指南这个免费的 Go 开源下载器支持 BT、磁力、ed2k还能让 AI 管任务下一篇终极Devise性能优化指南加速认证流程的10个实用技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表