云原生技术24-FinOps实践:让每一分钱都花在刀刃上,云原生成本优化:如何在K8s上省下50%的云账单

云原生成本优化:如何在K8s上省下50%的云账单

1、AI程序员系列文章

2、AI面试系列文章

3、AI编程系列文章


目录

1、开篇:当云账单成为噩梦

2、成本可视化:先看见,才能优化

为什么可视化是第一优先级?

Kubecost:开源成本分析的瑞士军刀

OpenCost:CNCF孵化的开源方案

云厂商成本分析工具

3、资源优化:Request/Limit的调优艺术

资源浪费的三大元凶

Request vs Limit:傻傻分不清?

黄金指标:如何科学设置 Request

实战:资源优化前后对比

4、弹性伸缩:让资源像呼吸一样自然

HPA:水平自动扩缩容

VPA:垂直自动扩缩容

Cluster Autoscaler:节点级弹性

5、调度优化:Spot实例的省钱秘籍

Spot实例:云厂商的"临期食品"

Karpenter:下一代节点调度器

混合实例策略:稳中带皮

6、存储优化:被遗忘的成本黑洞

存储成本:隐形的账单杀手

存储分层策略

生命周期管理:自动化的省钱利器

快照策略:备份不等于破产

7、治理策略:建立成本意识文化

命名空间配额:防止资源滥用

成本分摊标签:让每一分钱都有主

FinOps 文化:从"花钱"到"省钱"

8、总结与展望

成本优化效果总结

实施路线图

关键成功因素


开篇:当云账单成为噩梦

你是否遇到过这样的场景:

  • 月初收到云账单,手开始颤抖,心开始滴血 💔
  • K8s集群资源利用率不到10%,却还在疯狂扩容
  • 不知道谁在跑什么,只知道钱在哗哗流走
  • 老板问"为什么这个月云费用涨了30%",你只能尴尬地挠头

恭喜你,你患上了典型的"云原生成本失明症"。

💡效率技巧:根据FinOps Foundation的数据,企业平均在云原生环境中浪费**32%**的支出。这意味着如果你月云账单是10万,其中有3.2万是在烧钱取暖。

云原生成本优化不仅是技术问题,更是FinOps文化和工程实践的结合。本文将给出可落地的成本优化方案,帮助你从资源利用率10%提升至60%+,平均节省**30-50%**的云账单。


成本可视化:先看见,才能优化

为什么可视化是第一优先级?

想象一下:你走进一家餐厅,菜单上没有价格,服务员说"吃完再告诉你"。这就是没有成本可视化的K8s集群。

成本可视化的三大核心价值:

  1. 归因:知道谁在花多少钱
  2. 趋势:看清成本走向,避免"账单惊吓"
  3. 优化方向:找到最大的浪费点,对症下药

Kubecost:开源成本分析的瑞士军刀

┌─────────────────────────────────────────────────────────┐ │ Kubecost 架构 │ ├─────────────────────────────────────────────────────────┤ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Prometheus│───→│ Kubecost │───→│ Web UI │ │ │ │ (Metrics)│ │ Server │ │(Dashboard)│ │ │ └──────────┘ └────┬─────┘ └──────────┘ │ │ │ │ │ ↓ │ │ ┌─────────────────┐ │ │ │ Cloud Provider │ │ │ │ Billing API │ │ │ │ (AWS/Azure/GCP) │ │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────┘

Kubecost 安装(Helm方式):

# 添加 Helm 仓库 helm repo add kubecost https://kubecost.github.io/cost-analyzer/ helm repo update # 安装 Kubecost(免费版) helm install kubecost kubecost/cost-analyzer \ --namespace kubecost \ --create-namespace \ --set kubecostToken="your-token-here" # 暴露服务访问 kubectl port-forward --namespace kubecost \ deployment/kubecost-cost-analyzer 9090

访问http://localhost:9090后,你将看到:

  • 集群总成本概览
  • 按命名空间/Deployment/Pod 的成本拆分
  • 资源利用率热力图
  • 成本优化建议(如未充分利用的节点)

OpenCost:CNCF孵化的开源方案

⚠️避坑警告:Kubecost 的商业版功能强大,但免费版有数据保留限制。如果你需要完全开源的方案,OpenCost 是更好的选择。

OpenCost 安装:

kubectl apply --namespace opencost \ -f https://raw.githubusercontent.com/opencost/opencost/develop/kubernetes/opencost.yaml

OpenCost 的优势:

  • 完全开源,无商业限制
  • 支持多集群聚合
  • 提供标准 API,便于集成

云厂商成本分析工具

云厂商工具名称特色功能
AWSCost Explorer + CUR最成熟,支持标签分摊
AzureCost Management与AD集成好
GCPCloud BillingBigQuery导出强大
阿里云费用中心支持资源包分摊
腾讯云费用中心账单API较完善

💡效率技巧:无论使用什么工具,标签策略是成本可视化的基础。建议在集群创建时就规划好标签体系:

  • cost-center: 成本中心
  • team: 负责团队
  • project: 项目归属
  • environment: 环境(dev/staging/prod)

资源优化:Request/Limit的调优艺术

资源浪费的三大元凶

┌────────────────────────────────────────────────────────────┐ │ K8s 资源分配现状 │ ├────────────────────────────────────────────────────────────┤ │ │ │ 申请资源 (Request) ████████████████████ 100% │ │ 实际使用 ██░░░░░░░░░░░░░░░░░░ 15% │ │ 浪费资源 ░░░░░░░░░░░░░░░░░░░░ 85% ← 心疼 │ │ │ │ 限制资源 (Limit) ████████████████████████████████████ │ │ (通常设置得过高,从未触达) │ │ │ └────────────────────────────────────────────────────────────┘

资源浪费的幽默真相:

开发同学设置 Request 时的心态:“这个服务很重要,给2核4G吧,万一不够呢?”

实际上:服务峰值CPU使用率 0.05 核,内存使用 200MB。

这就像为了"万一"要搬家,每天背着一个空行李箱上班。

Request vs Limit:傻傻分不清?

概念作用类比
Request调度时保证的资源餐厅预订的座位
Limit运行时允许的最大资源餐厅的消防容量

⚠️避坑警告:Request 设置过低会导致 Pod 被频繁驱逐(OOMKilled),设置过高则造成资源浪费。Limit 设置过低会限制性能,设置过高则失去保护作用。

黄金指标:如何科学设置 Request

方法一:基于历史数据(推荐)

# 使用 kubectl top 查看实际使用情况 kubectl top pod -n your-namespace --containers # 输出示例: # NAME CPU(cores) MEMORY(bytes) # api-server-xxx 45m 256Mi # worker-xxx 120m 512Mi

设置 Request 的建议公式:

CPU Request = 平均使用 × 1.5 (预留50%缓冲) Memory Request = 峰值使用 × 1.2 (预留20%缓冲)

方法二:使用 VPA 自动推荐

apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: my-app-vpa spec: targetRef: apiVersion: apps/v1 kind: Deployment name: my-app updatePolicy: updateMode: "Off" # 先设为 Off 观察推荐值

查看 VPA 推荐:

kubectl get vpa my-app-vpa -o yaml

输出中的 recommendation 部分会给出建议的 Request 值。

实战:资源优化前后对比

假设一个微服务集群有 100 个 Pod,优化前:

指标优化前优化后节省
平均 CPU Request500m150m70%
平均 Mem Request1Gi400Mi60%
集群节点数20 台8 台60%
月度成本¥50,000¥20,00060%

弹性伸缩:让资源像呼吸一样自然

HPA:水平自动扩缩容

HPA(Horizontal Pod Autoscaler)根据负载自动调整 Pod 数量。

┌─────────────────────────────────────────────────────────────┐ │ HPA 工作原理 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 负载上升 │ │ ↓ │ │ ┌─────────────┐ │ │ │ CPU > 70% │ │ │ └──────┬──────┘ │ │ ↓ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 3 Pods │ ──→ │ 5 Pods │ ──→ │ 8 Pods │ │ │ │ (当前) │ │ (扩容) │ │ (继续扩容) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ 负载下降 │ │ ↓ │ │ ┌─────────────┐ │ │ │ CPU < 30% │ │ │ └──────┬──────┘ │ │ ↓ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 8 Pods │ ──→ │ 3 Pods │ │ │ │ (当前) │ │ (缩容) │ │ │ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

HPA 配置示例:

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: api-server-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: api-server minReplicas: 3 maxReplicas: 50 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80 behavior: scaleDown: stabilizationWindowSeconds: 300 # 缩容前等待5分钟,避免震荡 policies: - type: Percent value: 10 periodSeconds: 60

💡效率技巧:HPA 默认基于 CPU/Memory,但生产环境建议基于自定义指标(如 QPS、队列深度)。配合 Prometheus Adapter 使用效果更佳。

VPA:垂直自动扩缩容

VPA 调整单个 Pod 的资源 Request,适合:

  • 单 Pod 性能不足,但不想增加副本数
  • 批处理任务,资源需求波动大

⚠️避坑警告:VPA 和 HPA 不要同时基于 CPU/Memory 使用,会打架!建议 HPA 基于自定义指标,VPA 负责资源调优。

Cluster Autoscaler:节点级弹性

┌─────────────────────────────────────────────────────────────┐ │ Cluster Autoscaler 架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ │ │ │ Pending Pods │ ← 资源不足,Pod无法调度 │ │ └────────┬────────┘ │ │ ↓ │ │ ┌─────────────────┐ │ │ │ Cluster Autoscaler│ 检测到有Pod Pending │ │ └────────┬────────┘ │ │ ↓ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ 扩容节点 │ 或 │ 缩容空闲节点 │ │ │ │ (Scale Up) │ │ (Scale Down) │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

Cluster Autoscaler 安装(AWS EKS 示例):

# 下载 CA 配置 kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml # 配置 IAM 权限(略,详见 AWS 文档) # 编辑 Deployment,添加集群名称 kubectl edit deployment cluster-autoscaler -n kube-system # 修改命令行参数: # --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR_CLUSTER_NAME>

调度优化:Spot实例的省钱秘籍

Spot实例:云厂商的"临期食品"

┌─────────────────────────────────────────────────────────────┐ │ Spot 实例原理 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 云厂商数据中心 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ████████████████████████████████████████████████ │ │ │ │ ████ 按需实例 (On-Demand) ██████████████████████ │ │ │ │ ████████████████████████████████████████████████ │ │ │ │ │ │ │ │ ░░░░ 空闲资源 (Spot) ░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ │ │ ░░░░ 折扣 60-90% ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ │ │ ░░░░ 可被回收 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 类比:就像超市晚上8点后的临期食品,便宜但可能随时被买走 │ │ │ └─────────────────────────────────────────────────────────────┘

Spot 实例折扣对比:

云厂商实例类型按需价格Spot价格折扣
AWSm5.large$0.096/h$0.028/h71%
AzureD2s_v3$0.096/h$0.019/h80%
GCPn1-standard-2$0.095/h$0.019/h80%
阿里云ecs.c6.large¥0.62/h¥0.12/h81%

💡效率技巧:Spot 实例适合无状态、可中断的工作负载:

  • CI/CD 构建任务
  • 批处理/数据处理
  • 开发/测试环境
  • 可水平扩展的无状态服务

Karpenter:下一代节点调度器

Karpenter 是 AWS 推出的开源节点自动配置工具,比 Cluster Autoscaler 更智能。

apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: default spec: template: spec: requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand"] # 优先 Spot,按需兜底 - key: node.kubernetes.io/instance-type operator: In values: ["m5.large", "m5.xlarge", "m6i.large"] limits: cpu: 1000 memory: 4000Gi disruption: consolidationPolicy: WhenUnderutilized expireAfter: 720h # 30天后自动替换节点

Karpenter vs Cluster Autoscaler:

特性KarpenterCluster Autoscaler
启动速度快(无需预热ASG)慢(依赖ASG)
实例选择智能选择最优类型固定ASG配置
Spot 支持原生支持需额外配置
多架构支持ARM/x86 自动选择需多个ASG
学习曲线较陡平缓

混合实例策略:稳中带皮

┌─────────────────────────────────────────────────────────────┐ │ 混合实例策略架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 核心服务层 │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ API Gateway │ │ Auth Svc │ │ DB Primary │ │ │ │ │ │ (On-Demand) │ │ (On-Demand) │ │(On-Demand) │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 弹性计算层 │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ Worker Pod │ │ Worker Pod │ │ Worker Pod │ │ │ │ │ │ (Spot 70%) │ │ (Spot 70%) │ │(On-Demand) │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 批处理层 │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ Spark Job │ │ ML Training │ │ Data ETL │ │ │ │ │ │ (Spot 100%) │ │ (Spot 100%) │ │ (Spot 100%) │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘

实现混合实例的 Pod 亲和性配置:

apiVersion: apps/v1 kind: Deployment metadata: name: worker-service spec: replicas: 10 template: spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: karpenter.sh/capacity-type operator: In values: - spot - weight: 50 preference: matchExpressions: - key: node.kubernetes.io/instance-type operator: In values: - m5.large - m6i.large tolerations: - key: "spot" operator: "Equal" value: "true" effect: "NoSchedule" containers: - name: worker image: my-worker:latest resources: requests: cpu: 500m memory: 1Gi

存储优化:被遗忘的成本黑洞

存储成本:隐形的账单杀手

有一个笑话:云厂商最喜欢两种客户——

  1. 从来不看账单的客户
  2. 创建了EBS卷但从来不删的客户

存储成本现状:

存储类型单价 (AWS gp3)1TB 月费用
SSD (gp3)$0.08/GB$80
IO优化 (io2)$0.125/GB$125
冷存储$0.012/GB$12
归档存储$0.004/GB$4

⚠️避坑警告:一个集群如果有 100 个 Pod,每个 Pod 挂载 10GB PVC,即使这些 Pod 已经删除,PVC 可能还在默默计费。

存储分层策略

┌─────────────────────────────────────────────────────────────┐ │ 存储分层架构 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 热数据 (Hot) 温数据 (Warm) 冷数据 (Cold) │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ SSD/gp3 │ → │ 标准存储 │ → │ 归档存储 │ │ │ │ $0.08/GB │ │ $0.023/GB │ │ $0.004/GB │ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │ │ 使用场景: 使用场景: 使用场景: │ │ - 数据库 - 日志存储 - 备份数据 │ │ - 缓存 - 静态资源 - 历史归档 │ │ - 高频访问 - 中等访问 - 低频访问 │ │ │ └─────────────────────────────────────────────────────────────┘

PVC 存储类配置示例:

# 高性能存储类(数据库使用) apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast-ssd provisioner: ebs.csi.aws.com parameters: type: gp3 iops: "3000" throughput: "125" reclaimPolicy: Retain allowVolumeExpansion: true --- # 标准存储类(普通应用) apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: standard provisioner: ebs.csi.aws.com parameters: type: gp3 iops: "3000" reclaimPolicy: Delete # Pod删除时自动删除PV allowVolumeExpansion: true --- # 冷存储类(备份/归档) apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: cold-storage provisioner: ebs.csi.aws.com parameters: type: sc1 # 冷HDD reclaimPolicy: Delete

生命周期管理:自动化的省钱利器

使用 CronJob 自动清理过期数据:

apiVersion: batch/v1 kind: CronJob metadata: name: log-cleanup spec: schedule: "0 2 * * *" # 每天凌晨2点执行 jobTemplate: spec: template: spec: containers: - name: cleanup image: bitnami/kubectl:latest command: - /bin/sh - -c - | # 删除7天前的日志文件 kubectl exec -n logging deployment/log-aggregator -- \ find /var/log/app -name "*.log" -mtime +7 -delete # 清理未使用的 PVC(谨慎使用!) kubectl get pvc --all-namespaces | grep Terminating | \ awk '"'"'{print $2 " -n " $1}'"'"' | xargs -r kubectl delete pvc restartPolicy: OnFailure

快照策略:备份不等于破产

# VolumeSnapshotClass 配置 apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: csi-aws-snapclass driver: ebs.csi.aws.com parameters: # 快照保留策略 deletionPolicy: Retain --- # 定期快照 CronJob apiVersion: batch/v1 kind: CronJob metadata: name: volume-snapshot spec: schedule: "0 3 * * 0" # 每周日凌晨3点 jobTemplate: spec: template: spec: containers: - name: snapshot image: bitnami/kubectl:latest command: - /bin/sh - -c - | TIMESTAMP=$(date +%Y%m%d) kubectl create -f - <<EOF apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: db-snapshot-$TIMESTAMP namespace: production spec: volumeSnapshotClassName: csi-aws-snapclass source: persistentVolumeClaimName: db-data-pvc EOF # 只保留最近4个快照 kubectl get volumesnapshot -n production --sort-by=.metadata.creationTimestamp | \ tail -n +5 | awk '"'"'{print $1}'"'"' | xargs -r kubectl delete volumesnapshot -n production restartPolicy: OnFailure

治理策略:建立成本意识文化

命名空间配额:防止资源滥用

apiVersion: v1 kind: ResourceQuota metadata: name: team-alpha-quota namespace: team-alpha spec: hard: # 计算资源配额 requests.cpu: "20" requests.memory: 40Gi limits.cpu: "40" limits.memory: 80Gi # 存储配额 requests.storage: 500Gi persistentvolumeclaims: "10" # 对象数量配额 pods: "50" services: "10" secrets: "20" configmaps: "20" --- # 限制范围(LimitRange):设置默认值 apiVersion: v1 kind: LimitRange metadata: name: default-limits namespace: team-alpha spec: limits: - default: cpu: 500m memory: 512Mi defaultRequest: cpu: 100m memory: 128Mi type: Container

成本分摊标签:让每一分钱都有主

标签规范示例:

apiVersion: apps/v1 kind: Deployment metadata: name: payment-service labels: app.kubernetes.io/name: payment-service app.kubernetes.io/component: backend cost-center: "CC-001" team: "payments" project: "checkout-v2" environment: "production" owner: "zhangsan@company.com" spec: template: metadata: labels: cost-center: "CC-001" team: "payments" environment: "production"

基于标签的成本报告(Kubecost):

# 按团队查看成本 kubectl cost label --label team # 按项目查看成本 kubectl cost label --label project # 按环境查看成本 kubectl cost label --label environment

FinOps 文化:从"花钱"到"省钱"

FinOps 的三大阶段:

┌─────────────────────────────────────────────────────────────┐ │ FinOps 成熟度模型 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Crawl (爬行) Walk (行走) Run (奔跑) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 账单可见 │ → │ 成本优化 │ → │ 自动治理 │ │ │ │ 基础标签 │ │ 资源调优 │ │ 智能预测 │ │ │ │ 人工分析 │ │ 团队配额 │ │ 持续优化 │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 时间线:1-3个月 3-12个月 12个月+ │ │ │ └─────────────────────────────────────────────────────────────┘

建立成本意识的具体措施:

  1. 每周成本例会:各团队汇报资源使用情况和优化进展
  2. 成本仪表盘:在办公区大屏展示实时成本数据
  3. 成本优化竞赛:奖励节省成本最多的团队
  4. 自动告警:当某命名空间成本超过预算时自动通知

总结与展望

成本优化效果总结

优化领域优化前优化后节省比例
资源利用率10-15%60-70%55%
计算成本基准-30-50%
存储成本基准-40-60%
Spot 实例占比0%70%额外节省 60-90%

实施路线图

第1周:成本可视化 ├── 部署 Kubecost/OpenCost ├── 建立标签规范 └── 生成首份成本报告 第2-4周:资源优化 ├── 分析资源使用情况 ├── 调整 Request/Limit └── 部署 VPA(观察模式) 第5-8周:弹性伸缩 ├── 配置 HPA ├── 部署 Cluster Autoscaler └── 测试自动扩缩容 第9-12周:高级优化 ├── 引入 Spot 实例 ├── 存储分层 └── 建立配额和治理

关键成功因素

  1. 数据驱动:先度量,再优化
  2. 渐进式:不要试图一次解决所有问题
  3. 自动化:用工具代替人工检查
  4. 文化:让每个人都关心成本

文末三件套

1. 【源码获取】

关注此系列获取后续更新,后台回复‘cost’获取完整代码示例和配置文件链接。

2. 【思考题】

你的K8s集群资源利用率是多少?欢迎在评论区分享你的成本优化经验!

3. 【系列预告】

  • 安全最佳实践→ 如何在不牺牲安全的前提下优化成本
  • 性能调优→ 让应用跑得更快、花得更少
  • 监控告警→ 建立完善的成本监控体系
  • 故障排查→ 当成本异常时如何快速定位问题

CSDN标签

云原生 成本优化FinOpsKubecost资源优化Spot实例成本治理


本文首发于 CSDN,转载请注明出处。如有疑问,欢迎在评论区留言交流!