基于 K8s 容器集群的容灾架构与方案

news2024/11/25 1:43:59

作者:庄宇

在设计系统架构时,我们必须假设任何组件和任何基础设施可能会在任何时间失效,例如:自然灾害,电力中断,网络中断,错误的系统变更等。为了应对挑战,我们必须设计合适的容灾架构。

本文介绍如何以 K8s 集群(包括:ACK 集群,他云集群和本地 IDC K8s 集群)为基础,结合阿里云云产品(网络,数据库,中间件,可观测),设计容灾架构,构建一个“韧性”系统。

容灾目标

Recovery time objective(RTO):

服务中断与服务恢复之间可接受的最大延迟时间。决定服务停机的可接受时长。

Recovery point objective(RPO):

自上一个数据恢复点以来可接受的最大时间量。决定可接受的数据丢失或重建。

图片

对于 RTO 和 RPO,数值越低代表停机时间和数据丢失越少,但是越低的 RTO 和 RPO 会导致资源成本和运维复杂性越高。因此,您需要根据工作负载的重要性,指定适当的 RTO 和 RPO。

容灾策略

图片

上图中,描述的常见的 3 种容灾策略:备份与恢复、主备、双活,不同的容灾策略对应了不同的收益和成本。您需要综合分析业务的重要性、风险、可投入的成本等,以选择适合的容灾策略。

备份与恢复(Backup-Restore)

在系统运行时,备份应用和数据,在灾难发生时,在另一个地点恢复应用和数据,并切换业务流量。由于数据无法实时备份,在恢复数据时会有一定的数据丢失,同时如果数据量较大,恢复数据时间可能较长。

图片

主备(Active-Standby)

在主备模式中,主 Location 处理所有的业务流量,备用 location 可以启动较少的应用实例节省成本,并周期发送测试流量以验证系统有效性。在灾难发生时,做数据库主备切换,扩容应用实例数,并切换业务流量。

图片

双活(Active-Active)

在双活模式中,2 个 Location 启动相同的应用实例数,同时处理业务流量。在灾难发生时,做数据库主备切换,并切换业务流量。

图片

容灾范围

多可用区(Multi-AZ)

阿里云地域(Region) [ 11] 包含多个可用区(AZ),可用区(AZ)是电力和网络互相独立的物理区域,对停电,断网等局部中断的容灾场景,可以使用多个可用区(AZ)设计容灾策略。由于可用区间的网络延时较短,可以更容易实现数据部分的容灾方案,包括数据库、缓存和消息等。

多地域(Multi-Region)

为了应对更大范围的灾难故障事件,这些事件可能会影响同地域(Region)的多个可用区(AZ),您可以使用多个地域(Region)设计容灾策略。但由于地域间更大网络延时,容灾方案复杂度和实现成本较高。

在选择多可用区(AZ)或者多地域(Region)容灾方案时,需要重点考虑有状态应用和依赖的云产品(例如:数据库、缓存和消息)是否支持多地域或者多可用区容灾。

方案示例

备份与恢复(Backup & Restore)

公共云跨可用区和跨地域备份与恢复
  1. 通过 ACK One 备份中心 [3 ] ,可以备份 ACK 集群中的应用,包括无状态应用和有状态应用,对有状态应用,在备份应用 YAML 的同时可以备份相关 Storage 数据。

  2. ACK One 备份中心集成云产品云盘快照 [ 12] ,文件存储 NAS [13 ] ,对象存储 OSS [14 ] 和云备份 [15 ] ,分别支持应用 YAML,云盘 PV,文件系统 PV 的一键备份。

  3. 备份后,可以随时将应用和 Storage 数据,恢复到任意地域和可用区的 ACK 集群。

  4. 阿里云数据库服务的备份与恢复,可以参考相应数据产品的文档,例如:RDS MySQL 数据库备份恢复 [ 16] ,RDS 实例间数据迁移 [17 ]

图片

混合云备份与恢复
  1. 通过 ACK One 注册集群 [ 4] ,可以将 IDC 自建或者非阿里云 K8s 集群,接入到阿里云 ACK 控制台。

  2. 接入 ACK One 注册集群后,通过 ACK One 备份中心,可以备份 IDC 自建和非阿里云 K8s 集群中的应用,包括无状态应用和有状态应用,对有状态应用,在备份应用 YAML 的同时可以备份相关 Storage 数据。

  3. 备份后,可以随时将应用(Deployment/Statefulset)和数据(PV/PVC),恢复到任意地域和可用区的 ACK 集群。

图片

总结

备份恢复方案实施成本较低,但 RTO 和 RPO 相对较长,取决于数据量的大小和应用的复杂度。备份中心能够提供的全量备份+增量备份能力,减少 RTO 和 RPO 时间。

备份恢复作为容灾的兜底方案,重要性高,在系统运维的过程中,要保证备份的及时性和可恢复性。

另外,许多用户选择通过备份恢复功能实现应用的跨集群迁移,场景如下:

  1. 业务上云,将本地 IDC 集群中的应用,迁移到阿里云 ACK 集群中,参考 IDC 应用上云迁移 [ 18]

  2. 集群版本较老,版本升级有稳定性风险,可以先创建新版本集群,通过备份恢复将应用迁移到新版本集群运行,参考跨版本集群迁移 [ 19]

  3. 用户在收敛云账号或者组织调整时,需要跨账号集群接入 [ 20] 和跨集群迁移应用 [21 ]

多集群 Service

在应用迁移的过程中,由于应用的数量较多,需要分批迁移,同时应用间存在调用关系。此时,在网络打通的前提下,可以使用 ACK One 舰队多集群 Service [ 5] ,实现应用 Kubernetes Service 跨集群访问。如下图所示,ACK One 舰队多集群 Service,可以将 Cluster1 的 Applcation2 的 Kubernetes Service(包含 endpoints)注入到 Cluster2,Cluster2 上的 Application1 可以访问 Cluster1 上的 Application2。

图片

在专线拉通的前提下,通过 ACK One 注册集群,IDC 和非阿里云的 K8s 集群也可以是用 ACK One 舰队多集群 Service。

单地域多可用区容灾

基于 DNS 流量分发
  1. 通过 ACK One GitOps 应用分发 [6 ] ,在 2 个 ACK 集群中部署应用,实现基于 Git 仓库的持续一致性部署。

  2. 通过全局流量管理(GTM) [22 ] 做 DNS 解析实现负载分发,并监控系统运行健康状态,自动触发容灾切换。

  3. 每个 AZ 内,通过 ACK Ingress [ 7] 实现 7 层流量管理。

  4. 备集群和主集群的应用版本相同,但备集群节点较少,应用副本较少,节省成本。

  5. 在主系统不可用时,全局流量管理(GTM)会将服务域名 DNS 解析到备用系统,完成主备切换。

  6. 由于流量的增长,备集群中 ACK HPA [8 ] 会扩容应用副本,进而触发 ACK Cluster Autocaler [9 ] 扩容集群节点。

  7. 阿里云中间件(消息,缓存)的跨可用区容灾,可参考相关文档,例如:云消息队列 RocketMQ 版实例规格 [ 23] ,云消息队列 Kafka 版实例规格 [ 24] ,云原生内存数据库 Tair 容灾方案 [ 25]

  8. 阿里云数据库服务的跨可用区容灾,可参考相关文档,例如:RDS MySQL 数据库搭建高可用架构 [ 26]

🔔 注意:

  1. 本方案基于 DNS 流量转发,由于 DNS 缓存,在灾难事件发生时,部分业务依然路由到主系统,造成一定的业务损失。

  2. 需要在 2 个集群中分别配置维护 7 层 ingress 规则,成本高。系统正常运行状态:

图片

灾难事件发生,AZ 不可用时,系统主备切换,GTM 将流量切换到 AZ2,ACK Cluste2 的应用实例自动扩展,中间件和数据库多可用区高可用切换。

图片

基于 ACK One 多集群网关
  1. 通过 ACK One GitOps 应用分发,在 2 个 ACK 集群中部署应用,实现基于 Git 仓库的持续一致性部署。

  2. 通过 ACK One 多集群网关 [ 10] ,定义标准 K8s Ingress 规则(YAML 格式),实现 7 层流量治理,实现流量的主备模式分发。多集群网关为跨可用区高可用。

  3. 备集群和主集群的应用版本相同,但备集群节点较少,应用副本较少,节省成本。可以发送特定 http header 的测试流量,多集群网关转发到备集群以验证工作状态。

  4. 在主系统不可用时,ACK One 多集群网关会自动将业务流量备用系统,完成主备切换。

  5. 由于流量的增长,备集群中 ACK HPA 会扩容应用副本,进而触发 ACK Cluster Autocaler 扩容集群节点。

  6. 阿里云数据库服务的跨可用区容灾,可参考相关文档,例如:RDS MySQL 数据库搭建高可用架构。

🔔 注意:

  1. 本方案为 HTTP 七层流量转发,配合 7 层健康检查,主备切换时相比 DNS 方案,大幅减低业务流量损失。

  2. 网关侧统一支持基于 Ingress 规则的流量治理,相比 DNS 方案,合并了四层负载均衡 SLB 和七层 Ingress 网关,降低系统复杂度和维护成本。

系统正常运行状态:

图片

灾难事件发生,AZ 不可用时,系统主备切换,多集群网关(MSE 云原生网关)自动将流量切换到 AZ2 的 ACK Cluste2 中, 应用实例自动扩展。

图片

跨可用区双活

以上 2 个方案以主备模式为例,描述了系统架构。同样的架构,基于 DNS 流量分发和 ACK One 多集群网关也支持双活场景,可以配置流量分发比例(例如:50% : 50%),支持自动 failover 切换。在双活的场景下,每个集群中的应用副本数,需要根据流量分发比例确定,集群中需要配置弹性伸缩,以支持流量切换情况下的流量增长。

总结

单地域多可用区方案实现的成本较低,可以利用云产品(包括:网关,容器,中间件,数据库)多可用区部署和多可用区高可用,快速实现容灾,对业务改造较小。但此方案仅可应对单个可用区的灾难和故障,无法应对地域级的灾难故障。

单地域云+IDC 容灾方案

方案架构与单地域多可用区容灾方案类似,要点如下:

  1. 云上 VPC 与 IDC 建立专线连接,打通管控与数据通道。

  2. 通过 ACK One 注册集群接入 IDC 集群,使用阿里云强大可观测和安全能力,统一管理 IDC 集群和 ACK 集群。

  3. 通过 ACK One GitOps 应用分发,在 2 个集群中部署应用,实现基于 Git 仓库的持续一致性部署。

基于 DNS 流量分发(单地域云上和云下双活)

图片

基于 ACK One 多集群网关(单地域云上和云下双活)

图片

多地域容灾

如果业务规模大重要性高,服务的用户数量多范围广,单地域的容灾方案就无法满足业务高可用要求,这时需要多地域容灾方案。在多个地域独立部署业务系统,保证每个地域的业务系统具有单独闭环提供完整的服务能力。

  1. 通过全局流量管理(GTM)实现用户就近接入相应地域。

  2. 通过 ACK One GitOps 应用分发,在 2 个 ACK 集群中部署应用,实现基于 Git 仓库的持续一致性部署。

  3. 缓存多地域高可用方案,可以参考阿里云产品相关文档,例如:Tair 全球多话 [ 27]

  4. 数据库跨地域高可用方案,可以参考阿里数据库云产品相关文档,例如:云原生数据库 PolarDB MySQL 全球数据库 [ 28]

  5. 地域内,可以采用单地域多可用区容灾方案。

图片

单元化多活部署

区别与前一方案,多地域单元化多活部署,需要设计分片规则对应用和数据进行分片,使得单元提供面向部分数据分片的完整服务能力,实现业务安全故障隔离,水平扩展,服务庞大的用户群体。一般分为中心单元(拥有所有用户数据)和多个子单元(分片后详细数据)。此种方式需要业务系统支持,自定义分流规则,数据拆分,单元间配合等,复杂度高。

图片

总结

各种灾难事件会影响您业务的可用性,通过使用阿里云的相关云产品的容灾能力,可以减轻或者消除这些影响。首先,需要了解业务可用性需求,从而选择一个适当的容灾策略,然后,使用阿里云相关云产品,包括:容器(容器服务 Kubernetes 版 ACK [ 1] 和分布式云容器平台 ACK One [ 2] )、消息、缓存、数据库等,设计容灾架构,快速达到您业务可用性要求的恢复时间目标 RTO 和恢复点目标 RPO。

相关链接:

[1] 容器服务 Kubernetes 版 ACK

https://help.aliyun.com/zh/ack/

[2] 分布式云容器平台 ACK One

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/product-overview/ack-one-overview

[3] ACK One 备份中心

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/backup-center-overview

[4] ACK One 注册集群

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/overview-9

[5] ACK One 舰队多集群 Service

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/mcs-overview

[6] ACK One GitOps 应用分发

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/gitops-overview

[7] ACK Ingress

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/ingress-overview

[8] ACK HPA

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/horizontal-pod-autoscaling

[9] ACK Cluster Autocaler

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/auto-scaling-of-nodes

[10] ACK One 多集群网关

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/multi-cluster-gateway-overview

[11] 地域(Region)

https://help.aliyun.com/document_detail/40654.html#concept-z04-bg5-j8w

[12] 云盘快照

https://help.aliyun.com/zh/ecs/user-guide/copy-a-snapshot

[13] 文件存储 NAS

https://help.aliyun.com/zh/nas/product-overview/what-is-nas

[14] 对象存储 OSS

https://help.aliyun.com/zh/oss/product-overview/what-is-oss

[15] 云备份

https://help.aliyun.com/zh/cloud-backup/product-overview/what-is-hbr

[16] RDS MySQL 数据库备份恢复

https://help.aliyun.com/zh/flink/developer-reference/log-service-connector

[17] RDS 实例间数据迁移

https://help.aliyun.com/zh/rds/apsaradb-rds-for-mysql/migrate-data-between-apsaradb-rds-for-mysql-instances

[18] IDC 应用上云迁移

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/migrate-applications-from-self-managed-kubernetes-clusters-to-ack-clusters

[19] 跨版本集群迁移

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/use-backup-center-to-migrate-applications-from-clusters-running-lower-kubernetes-versions

[20] 跨账号集群接入

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/use-cases/use-ack-one-to-manage-clusters-across-cloud-platforms-and-alibaba-cloud-accounts

[21] 跨集群迁移应用

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/migrate-applications-across-clusters-in-different-regions

[22] 全局流量管理(GTM)

https://help.aliyun.com/document_detail/189587.html

[23] 云消息队列 RocketMQ 版实例规格

https://help.aliyun.com/zh/apsaramq-for-rocketmq/cloud-message-queue-rocketmq-5-x-series/product-overview/instance-specifications

[24] 云消息队列 Kafka 版实例规格

https://help.aliyun.com/zh/apsaramq-for-kafka/cloud-message-queue-for-kafka/product-overview/instance-editions

[25] 云原生内存数据库 Tair 容灾方案

https://help.aliyun.com/zh/tair/product-overview/disaster-recovery

[26] RDS MySQL 数据库搭建高可用架构

https://help.aliyun.com/zh/rds/apsaradb-rds-for-mysql/build-a-high-availability-architecture

[27] Tair 全球多话

https://help.aliyun.com/zh/tair/user-guide/overview-of-global-distributed-cache-for-tair

[28] 云原生数据库 PolarDB MySQL 全球数据库

https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/overview-49

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1523157.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML基础:head头部标签包含的8种形式详解

你好&#xff0c;我是云桃桃。 HTML <head> 标签用于定义文档的头部&#xff0c;包含了一些元数据和引用的外部资源&#xff0c;但并不会直接展示在页面上。<head> 标签位于 <html> 标签内部&#xff0c;紧跟在 <html> 开始标签之后&#xff0c;在 &l…

贪心算法(两个实例)

例一&#xff1a;调度问题 问题&#xff1a;由n项任务&#xff0c;每项任务的加工时间已知&#xff0c;从零时刻开始陆续加入一台机器上去加工&#xff0c;每个任务完成的时间是从0时刻到任务加工截至的时间。 求总完成时间&#xff08;所有任务完成时间最短计划方案&#xf…

C语言字符函数和字符串函数详解

Hello, 大家好&#xff0c;我是一代&#xff0c;今天给大家带来有关字符函数和字符串函数的有关知识 所属专栏&#xff1a;C语言 创作不易&#xff0c;望得到各位佬们的互三呦 一.字符函数 在C语言中有一些函数是专门为字符设计的&#xff0c;这些函数的使用都需要包含一个头文…

SQLiteC/C++接口详细介绍之sqlite3类(十七)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十六&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;十八&#xff09; ​ 53.sqlite3_trace_v2 函数功能&#x…

EXCEL+PYTHON学习3

1&#xff09; 遍历一个SHEET&#xff0c;无非就是两个循环&#xff0c;rows属性是取得所有行。 fn data3_16.xlsx wb openpyxl.load_workbook(fn) ws wb.active for row in ws.rows:for cell in row:print(cell.value, end )print() 2&#xff09; 返回工作表的最小行数…

【Leetcode-54.螺旋矩阵】

题目&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1…

Day38:安全开发-JavaEE应用SpringBoot框架MyBatis注入Thymeleaf模版注入

目录 SpringBoot-Web应用-路由响应 SpringBoot-数据库应用-Mybatis SpringBoot-模版引擎-Thymeleaf 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用等. 框架…

基于springboot实现房源出租信息系统项目【项目源码+论文说明】

基于springboot实现房源出租信息系统演示 摘要 近些年来在一线城市的房子需求量在逐步递增&#xff0c;其中租房子和出租房子的需求业务不断增加。那么租房对于我们一线二线城市来说是一个非常大&#xff0c;而且具有经济提升能力的业务场景。那么信息技术在此行业的加持早已是…

JavaWeb--HTML

一&#xff1a;HTML简介 *HTML是一门语言&#xff0c;所有的网页都是用HTML这门语言编写出来的&#xff1b; *HTML&#xff1a;超文本标记语言&#xff1b; 超文本&#xff1a;超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&#xff0c;还能定义图片&#xff…

展开说说:Android之SharedPreferences

SharedPreferences 是一种轻量级的数据持久化存储机制。以key/value键值对形式存储在xml文件&#xff0c;用于保存一些应用程序数据。保存在 /data/data/PACKAGE_NAME/shared_prefs/xxx.Xml文件。 SharedPreferences 只能存储string&#xff0c;int&#xff0c;float&#xff…

visual studio2019项目中引入头文件失效问题的解决

这几天把项目整理一下&#xff0c;但在引入头文件过程中非常曲折。 项目本身写好了可以运行&#xff0c;但是项目结构是这样的&#xff1a; 所以想把功能模块化&#xff0c;同一类协议功能放在一起。 于是建包&#xff0c;创建文件&#xff0c;导入头文件&#xff1a; 在新…

瑞熙贝通打造智慧校园实验室安全综合管理平台

一、建设思路 瑞熙贝通实验室安全综合管理平台是基于以实验室安全&#xff0c;用现代化管理思想与人工智能、大数据、互联网技术、物联网技术、云计算技术、人体感应技术、语音技术、生物识别技术、手机APP、自动化仪器分析技术有机结合&#xff0c;通过建立以实验室为中心的管…

zookeeper基础学习之六: zookeeper java客户端curator

简介 Curator是Netflix公司开源的一套zookeeper客户端框架&#xff0c;解决了很多Zookeeper客户端非常底层的细节开发工作&#xff0c;包括连接重连、反复注册Watcher和NodeExistsException异常等等。Patrixck Hunt&#xff08;Zookeeper&#xff09;以一句“Guava is to Java…

微信小程序开发系列(三十四)·自定义组件的创建、注册以及使用(数据和方法事件的使用)

目录 1. 分类和简介 2. 公共组件 2.1 创建 2.2 注册 2.3 使用 3. 页面组件 3.1 创建 3.2 注册 3.3 使用 4. 组件的数据和方法的使用 4.1 组件数据的修改 4.2 方法事件的使用 1. 分类和简介 小程序目前已经支持组件化开发&#xff0c;可以将页面中的功能…

【PyTorch】基础学习:一文详细介绍 torch.load() 的用法和应用

【PyTorch】基础学习&#xff1a;一文详细介绍 torch.load() 的用法和应用 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f44…

基于Android Studio的小米便签App的代码泛读结对心得体会

本次实验我本来最开始使用的是2023.2.1.23的Android studio版本&#xff0c;但是在选择项目的时候没有编程语言为java的选项导致导入项目之后运行不起来。 创建完项目之后默认的代码块是MainActivity.kt&#xff0c;这里面不能编写java代码 所以我选择了退版本退到21海豚版本…

AcWing 2. 01背包问题

题目描述 解题思路&#xff1a; 相关代码&#xff1a; import java.util.Scanner; public class Main {public static void main(String[] args){Scanner scanner new Scanner(System.in);/** 背包问题的物品下标最好从1开始。* *//*定义一f[i][j]数组&#xff0c;i表示的…

Java学习笔记------常用API(五)

爬虫 从网站中获取 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.reg…

论文浅尝 | GPT-RE:基于大语言模型针对关系抽取的上下文学习

笔记整理&#xff1a;张廉臣&#xff0c;东南大学硕士&#xff0c;研究方向为自然语言处理、信息抽取 链接&#xff1a;https://arxiv.org/pdf/2305.02105.pdf 1、动机 在很多自然语言处理任务中&#xff0c;上下文学习的性能已经媲美甚至超过了全资源微调的方法。但是&#xf…

2022年第十三届蓝桥杯比赛Java B组 【全部真题答案解析-第一部分】

最近回顾了Java B组的试题&#xff0c;深有感触&#xff1a;脑子长时间不用会锈住&#xff0c;很可怕。 兄弟们&#xff0c;都给我从被窝里爬起来&#xff0c;赶紧开始卷&#xff01;&#xff01;&#xff01; 2022年第十三届蓝桥杯Java B组(第一部分 A~F题) 目录 一、填空题 …