从零开始学架构——可扩展架构模式

news2024/11/16 11:47:24

可扩展架构模式的基本思想和模式

软件系统与硬件和建筑系统最大的差异在于软件是可扩展的,一个硬件生产出来后就不会再进行改变、一个建筑完工后也不会再改变其整体结构
例如,一颗 CPU 生产出来后装到一台 PC 机上,不会再返回工厂进行加工以增加新的功能;金字塔矗立千年历经风吹雨打,但其现在的结构和当时建成完工时的结构并无两样。
相比之下,软件系统就完全相反,真正有生命力的软件系统,都是在不断迭代和发展的。典型的如 Windows 操作系统,从 Windows 3.0 到 Windows 95 到 Windows XP,直到现在的 Windows 10,一直在跟着技术的发展而不断地发展。如果一个软件系统开发出来后,再也没有任何更新和调整,反而说明了这套软件系统没有发展、没有生命力。
软件系统的这种天生和内在的可扩展的特性,既是魅力所在,又是难点所在。

  • 魅力体现在我们可以通过修改和扩展,不断地让软件系统具备更多的功能和特性,满足新的需求或者顺应技术发展的趋势。
  • 难点体现在如何以最小的代价去扩展系统,因为很多情况下牵一发动全身,扩展时可能出现到处都要改,到处都要推倒重来的情况。这样做的风险不言而喻:改动的地方越多,投入也越大,出错的可能性也越大。

因此,如何避免扩展时改动范围太大,是软件架构可扩展性设计的主要思考点。

可扩展的基本思想

可扩展性架构的设计方法很多,但万变不离其宗,所有的可扩展性架构设计,背后的基本思想都可以总结为一个字:拆!
拆,就是将原本大一统的系统拆分成多个规模小的部分,扩展时只修改其中一部分即可,无须整个系统到处都改,通过这种方式来减少改动范围,降低改动风险。
面对软件系统,拆没那么简单,因为我们并不是要摧毁一个软件系统,而是要通过拆让软件系统变得更加优美(具备更好的可扩展性)。形象地说,软件系统中的“拆”是建设性的,因此难度要高得多。
按照不同的思路来拆分软件系统,就会得到不同的架构。常见的拆分思路有如下三种

  • 面向流程拆分:将整个业务流程拆分为几个阶段,每个阶段作为一部分
  • 面向服务拆分:将系统提供的服务拆分,每个服务作为一部分
  • 面向功能拆分:将系统提供的功能拆分,每个功能作为一部分

理解这三种思路的关键就在于如何理解“流程”、“服务”、“功能”三者的联系和区别。
从范围上来看,从大到小依次为:流程 > 服务 > 功能,单纯从概念解释可能难以理解,但实际上看几个案例就很清楚了
以TCP/IP协议栈为例:
在这里插入图片描述

  • 流程
    对应 TCP/IP 四层模型,因为 TCP/IP 网络通信流程是:应用层 → 传输层 → 网络层 → 物理 + 数据链路层,不管最上层的应用层是什么,这个流程都不会变。
  • 服务
    对应应用层的 HTTP、FTP、SMTP 等服务,HTTP 提供 Web 服务,FTP 提供文件服务,SMTP 提供邮件服务,以此类推
  • 功能
    每个服务都会提供相应的功能。例如,HTTP 服务提供 GET、POST 功能,FTP 提供上传下载功能,SMTP 提供邮件发送和收取功能
    以一个简单的学生信息管理系统为例,拆分方式是:
  1. 面向流程拆分
    展示层 → 业务层 → 数据层 → 存储层,各层含义是:
    展示层:负责用户页面设计,不同业务有不同的页面。例如,登录页面、注册页面、信息管理页面、安全设置页面等
    业务层:负责具体业务逻辑的处理。例如,登录、注册、信息管理、修改密码等业务
    数据层:负责完成数据访问。例如,增删改查数据库中的数据、记录事件到日志文件等
    存储层:负责数据的存储。例如,关系型数据库 MySQL、缓存系统 Memcache 等
    最终架构如下,
    在这里插入图片描述

  2. 面向服务拆分
    将系统拆分为注册、登录、信息管理、安全设置等服务,最终架构示意图如下:
    在这里插入图片描述

  3. 面向功能拆分
    每个服务都可以拆分为更多注册服务:提供多种方式进行注册,包括手机号注册、身份证注册、学生邮箱注册三个功能。
    登录服务:包括手机号登录、身份证登录、邮箱登录三个功能。
    信息管理服务:包括基本信息管理、课程信息管理、成绩信息管理等功能。
    安全设置服务:包括修改密码、安全手机、找回密码等功能细粒度的功能,例如:
    在这里插入图片描述

通过学生信息管理系统的案例可以发现,不同的拆分方式,架构图差异很大。但好像无论哪种方式,最终都是可以实现的。既然如此,我们何必费尽心机去选择呢,随便挑选一个不就可以了?

当然不能随便挑,否则架构设计就没有意义了,架构师也就要丢掉饭碗了。原因在于:不同的拆分方式,本质上决定了系统的扩展方式。

可扩展方式

当我们谈可扩展性时,很多同学都会有一个疑惑:就算是不拆分系统,只要在设计和写代码时做好了,同样不会出现到处改的问题啊?例如,在面向服务拆分的案例中,增加“学号注册”,就算是不拆分为服务,也可以控制修改的范围,那为何我们要大费周章地去拆分系统呢?
在一个理想的环境,你的团队都是高手,每个程序员都很厉害,对业务都很熟悉,新来的同事很快就知晓所有的细节……那确实不拆分也没有问题。但现实却是:团队有菜鸟程序员,到底是改 A 处实现功能还是改 B 处实现功能,完全取决于他觉得哪里容易改;有的程序员比较粗心;有的程序员某天精神状态不太好;新来的同事不知道历史上某行代码为何那么“恶心”,而轻易地将其改漂亮了一些……所有的这些问题都可能出现,这时候你就会发现,合理的拆分,能够强制保证即使程序员出错,出错的范围也不会太广,影响也不会太大
下面是不同拆分方式应对扩展时的优势。

  1. 面向流程拆分
    扩展时大部分情况只需要修改某一层,少部分情况可能修改关联的两层,不会出现所有层都同时要修改
    -例如学生信息管理系统,如果我们将存储层从 MySQL 扩展为同时支持 MySQL 和 Oracle,那么只需要扩展存储层和数据层即可,展示层和业务层无须变动
  2. 面向服务拆分
    对某个服务扩展,或者要增加新的服务时,只需要扩展相关服务即可,无须修改所有的服务
    同样以学生管理系统为例,如果我们需要在注册服务中增加一种“学号注册”功能,则只需要修改“注册服务”和“登录服务”即可,“信息管理服务”和“安全设置”服务无须修改
  3. 面向功能拆分
    对某个功能扩展,或者要增加新的功能时,只需要扩展相关功能即可,无须修改所有的服务
    同样以学生管理系统为例,如果我们增加“学号注册”功能,则只需要在系统中增加一个新的功能模块,同时修改“登录功能”模块即可,其他功能都不受影响
    不同的拆分方式,将得到不同的系统架构,典型的可扩展系统架构有:
  • 面向流程拆分:分层架构
  • 面向服务拆分:SOA、微服务
  • 面向功能拆分:微内核架构

当然,这几个系统架构并不是非此即彼的,而是可以在系统架构设计中进行组合使用的。以学生管理系统为例,我们最终可以这样设计架构:
整体系统采用面向服务拆分中的“微服务”架构,拆分为“注册服务”“登录服务”“信息管理服务”“安全服务”,每个服务是一个独立运行的子系统。
其中的“注册服务”子系统本身又是采用面向流程拆分的分层架构。
“登录服务”子系统采用的是面向功能拆分的“微内核”架构。

传统可扩展架构模式:分层架构和SOA

相比于高性能、高可用架构模式在最近几十年的迅猛发展来说,可扩展架构模式的发展可以说是步履蹒跚
最近几年火热的微服务模式算是可扩展模式发展历史中为数不多的亮点
这也导致了现在谈可扩展的时候必谈微服务,甚至微服务架构都成了架构设计的银弹,高性能也用微服务、高可用也用微服务
很多时候这样的架构设计看起来高大上,实际上违背了架构设计的“合适原则”和“简单原则”
在实践中更好的进行可扩展架构设计,接下来将分别介绍几种可扩展架构模式,指出每种架构模式的关键点和优缺点。

分层架构

分层架构是很常见的架构模式,它也叫 N 层架构,通常情况下,N 至少是 2 层。例如,C/S 架构、B/S 架构。常见的是 3 层架构(例如,MVC、MVP 架构)、4 层架构,5 层架构的比较少见,一般是比较复杂的系统才会达到或者超过 5 层,比如操作系统内核架构。
按照分层架构进行设计时,根据不同的划分维度和对象,可以得到多种不同的分层架构

  • C/S 架构、B/S 架构
    划分的对象是整个业务系统,划分的维度是用户交互,即将和用户交互的部分独立为一层,支撑用户交互的后台作为另外一层。例如,下面是 C/S 架构结构图
    C/S 架构结构图

  • MVC 架构、MVP 架构
    划分的对象是单个业务子系统,划分的维度是职责,将不同的职责划分到独立层,但各层的依赖关系比较灵活。例如,MVC 架构中各层之间是两两交互的:
    MVC 架构图

  • 逻辑分层架构
    划分的对象可以是单个业务子系统,也可以是整个业务系统,划分的维度也是职责。虽然都是基于职责划分,但逻辑分层架构和 MVC 架构、MVP 架构的不同点在于,逻辑分层架构中的层是自顶向下依赖的。典型的有操作系统内核架构、TCP/IP 架构。例如,下面是 Android 操作系统架构图:
    Android 操作系统架构图
    典型的 J2EE 系统架构也是逻辑分层架构,架构图如下:
    J2EE 系统架构
    针对整个业务系统进行逻辑分层的架构图如下:
    在这里插入图片描述
    无论采取何种分层维度,分层架构设计最核心的一点就是需要保证各层之间的差异足够清晰,边界足够明显,让人看到架构图后就能看懂整个架构,这也是分层不能分太多层的原因。否则如果两个层的差异不明显,就会出现程序员小明认为某个功能应该放在 A 层,而程序员老王却认为同样的功能应该放在 B 层,这样会导致分层混乱。如果这样的架构进入实际开发落地,则 A 层和 B 层就会乱成一锅粥,也就失去了分层的意义。

分层架构之所以能够较好地支撑系统扩展,本质在于隔离关注点(separation of concerns),即每个层中的组件只会处理本层的逻辑。
比如说,展示层只需要处理展示逻辑,业务层中只需要处理业务逻辑,这样我们在扩展某层时,其他层是不受影响的,通过这种方式可以支撑系统在某层上快速扩展。例如,Linux 内核如果要增加一个新的文件系统,则只需要修改文件存储层即可,其他内核层无须变动。

当然,并不是简单地分层就一定能够实现隔离关注点从而支撑快速扩展,分层时要保证层与层之间的依赖是稳定的,才能真正支撑快速扩展。例如,Linux 内核为了支撑不同的文件系统格式,抽象了 VFS 文件系统接口,架构图如下
在这里插入图片描述
如果没有VFS,只是简单地将ext2、ext3、reiser等文件系统划分为“文件系统层”,那么这个分层是达不到支撑可扩展的目的的。因为增加一个新的文件系统后,所有基于文件系统的功能都要适配新的文件系统接口;而有了VFS后,只需要VFS适配新的文件系统接口,其他基于文件系统的功能以来的是VFS,不会受到影响。

分层结构的另外一个特点就是层层传递,也就是说一旦分层确定,整个业务流程是按照层进行依次传递的,不能在层之间进行跳跃。

最简单的 C/S 结构,用户必须先使用 C 层,然后 C 层再传递到 S 层,用户是不能直接访问 S 层的。传统的 J2EE 4 层架构,收到请求后,必须按照下面的方式传递请求:
在这里插入图片描述

分层结构的这种约束,好处在于强制将分层依赖限定为两两依赖,降低了整体系统复杂度。

举个例子
Persistence Layer如下,

public class AvatarDao {
    public static String getAvatarUrl(int userId){
        // 具体实现代码 略
        return "http://avatar.csdn.net/xxx.jpg";
    }
}

Business Layer如下,

public class AvatarBizz {
    public static String getAvatarUrl(int userId){
        return AvatarDao.getAvatarUrl(userId);
    }
}

Presentation Layer如下,

public class AvatarView {
    public void displayAvatar(int userId) {
        String url = AvatarBizz.getAvatarUrl(userId);
        // 渲染代码略
        return;
    }
}

例如,Business Layer 被 Presentation Layer 依赖,自己只依赖Persistence Layer。但分层结构的代价就是冗余,也就是说,不管这个业务有多么简单,每层都必须要参与处理,甚至可能每层都写了一个简单的包装函数。分层架构的优势就体现在通过分层强制约束两两依赖,一旦自由选择绕过分层,时间一长,架构就会变得混乱。

例如,Presentation Layer 直接访问 Persistence Layer,Business Layer 直接访问 Database Layer,这样做就失去了分层架构的意义,也导致后续扩展时无法控制受影响范围,牵一发动全身,无法支持快速扩展。
除此以外,虽然分层架构的实现在某些场景下看起来有些啰嗦和冗余,但复杂度却很低
分层架构另外一个典型的缺点就是性能,因为每一次业务请求都需要穿越所有的架构分层,有一些事情是多余的,多少都会有一些性能的浪费

这里所谓的性能缺点只是理论上的分析,实际上分层带来的性能损失,如果放到 20 世纪 80 年代,可能很明显
但到了现在,硬件和网络的性能有了质的飞越,其实分层模式理论上的这点性能损失,在实际应用中,绝大部分场景下都可以忽略不计

SOA

SOA 的全称是 Service Oriented Architecture,中文翻译为“面向服务的架构”。SOA 出现 的背景是企业内部的 IT 系统重复建设且效率低下,主要体现在:

  • 企业各部门有独立的 IT 系统,比如人力资源系统、财务系统、销售系统,这些系统可能都涉及人员管理,各 IT 系统都需要重复开发人员管理的功能。例如,某个员工离职后,需要分别到上述三个系统中删除员工的权限。
  • 各个独立的 IT 系统可能采购于不同的供应商,实现技术不同,企业自己也不太可能基于这些系统进行重构。
  • 随着业务的发展,复杂度越来越高,更多的流程和业务需要多个 IT 系统合作完成。由于各个独立的 IT 系统没有标准的实现方式(例如,人力资源系统用 Java 开发,对外提供 RPC;而财务系统用 C# 开发,对外提供 SOAP 协议),每次开发新的流程和业务,都需要协调大量的 IT 系统,同时定制开发,效率很低。

为了应对传统 IT 系统存在的问题,SOA 提出了 3 个关键概念

服务

所有业务功能都是一项服务,服务就意味着要对外提供开放的能力,当其他系统需要使用这项功能时,无须定制化开发。服务可大可小,可简单也可复杂。
例如,人力资源管理可以是一项服务,包括人员基本信息管理、请假管理、组织结构管理等功能。
而人员基本信息管理也可以作为一项独立的服务。
组织结构管理也可以作为一项独立的服务。
到底是划分为粗粒度的服务,还是划分为细粒度的服务,需要根据企业的实际情况进行判断。

ESB

ESB 的全称是 Enterprise Service Bus,中文翻译为“企业服务总线”。
从名字可以看出,ESB 参考了计算机总线的概念。
计算机中的总线将各个不同的设备连接在一起,ESB 将企业中各个不同的服务连接在一起。
因为各个独立的服务是异构的,如果没有统一的标准,则各个异构系统对外提供的接口是各式各样的。
SOA 使用 ESB 来屏蔽异构系统对外提供各种不同的接口方式,以此来达到服务间高效的互联互通。

松耦合

松耦合的目的是减少各个服务间的依赖和互相影响。
因为采用 SOA 架构后,各个服务是相互独立运行的,甚至都不清楚某个服务到底有多少对其他服务的依赖。
如果做不到松耦合,某个服务一升级,依赖它的其他服务全部故障,这样肯定是无法满足业务需求的。
实际上真正做到松耦合并没有那么容易,要做到完全后向兼容,是一项复杂的任务。

典型的SOA架构图

SOA 架构是比较高层级的架构设计理念,一般情况下我们可以说某个企业采用了 SOA 的架构来构建 IT 系统,但不会说某个独立的系统采用了 SOA 架构
SOA 解决了传统 IT 系统重复建设和扩展效率低的问题,但其本身也引入了更多的复杂性。SOA 最广为人诟病的就是 ESB,ESB 需要实现与各种系统间的协议转换、数据转换、透明的动态路由等功能。下图就是ESB将JSON转换为Java的流程图,
在这里插入图片描述
下图中ESB将REST协议转换为RMI和AMQP两个不同的协议:
在这里插入图片描述
ESB 虽然功能强大,但现实中的协议有很多种,如 JMS、WS、HTTP、RPC 等,数据格式也有很多种,如 XML、JSON、二进制、HTML 等
ESB 要完成这么多协议和数据格式的互相转换,工作量和复杂度都很大,而且这种转换是需要耗费大量计算性能的。
当 ESB 承载的消息太多时,ESB 本身会成为整个系统的性能瓶颈。

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

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

相关文章

从零玩转前后端加解密之SM2-sm2

title: 从零玩转前后端加解密之SM2 date: 2022-08-21 19:42:00.907 updated: 2023-03-30 13:28:48.866 url: https://www.yby6.com/archives/sm2 categories: - 加密算法 - 从零玩转系列 tags: - 加密算法 - sm2 前言 SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥…

工业互联网UWB定位系统源码,支持自定义开发

工厂人员定位系统,采用UWB定位技术,通过在厂区内部署一定数量的定位基站,以及为人员、车辆、物资佩戴标签卡的形式,实时获取人员精确位置,精度高达10cm。 文末获取联系 工厂人员定位系统可实现物资/车辆实时定位&#…

不同厂家对讲机耳塞耳挂/领夹型988对讲机如何写频改频点/频率能互相通信

988型号都是很多厂家代工出来的,代工出来默认的频点都不一样,有可能买回来的2个不同厂家生产的对讲机,这样它们要能通讯,必须要同频点才能互通,它一般出厂设定16个频道,长按+和-键来切换频道。 需要用到typeC 的写频线,其实是用CH430芯片的usb写频线,可以找厂家要写频线…

编程语言中,循环变量通常都用 i?你知道为什么吗?

01 前天,我在朋友圈发了一个问题: 为什么编程中,循环变量通常都是用 i ? 没想到,回复的人这么多!要连翻好几页。 这个问题,有 2/3 的人回答正确,有少部分人知道,但是不太确定。 习惯…

Hadoop基础学习---2、Hadoop概述

1、Hadoop概述 1.1 Hadoop是什么? 1、Hadoop是一个又Apache基金会所开发的分布式系统基础架构。 2、主要解决海量数据的存储和海量数据的分析计算。 3、广义上来说,Hadoop通常是指一个更广泛的概念——Hadoop生态圈。 1.2 Hadoop 优势(4高…

六级备考28天|CET-6|翻译井冈山|2021年12月|8:20~9:40+ ~10:17

目录 四级翻译5篇必练真题 六级翻译5篇必练真题 井冈山 四级翻译5篇必练真题 ①2023年3月一卷①自驾游 ②2022年 12月一卷③立秋 ③2022年6月一卷①拔苗助长 ④2021年 12月一卷②大运河 ⑤2021年6月一卷③普洱茶 六级翻译5篇必练真题 ①2023年3月一卷②郑和下西洋 ②2022年…

微服务多模块:Springboot+Security+Redis+Gateway+OpenFeign+Nacos+JWT (附源码)仅需一招,520彻底拿捏你

可能有些人会觉得这篇似曾相识,没错,这篇是由原文章进行二次开发的。 前阵子有些事情,但最近看到评论区说原文章最后实现的是单模块的验证,由于过去太久也懒得验证,所以重新写了一个完整的可以跑得动的一个。 OK&#…

nvidia-smi 失效解决

服务器重启后,跑模型发现: RuntimeError: Attempting to deserialize object on a CUDA device but torch.cuda.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_locationtorch.device(cpu) to ma…

Linux常用命令——hping3命令

在线Linux命令查询工具 hping3 测试网络及主机的安全 补充说明 hping是用于生成和解析TCPIP协议数据包的开源工具。创作者是Salvatore Sanfilippo。目前最新版是hping3,支持使用tcl脚本自动化地调用其API。hping是安全审计、防火墙测试等工作的标配工具。hping优…

【开源项目】Nepxion Aquarius实现分布式锁、缓存、ID生成、限速的源码解读

项目地址 项目地址 https://toscode.gitee.com/nepxion/Aquarius 项目介绍 Nepxion Aquarius是一款基于Redis Zookeeper的分布式应用组件集合,包含分布式锁,缓存,ID生成器,限速限流器。它采用Nepxion Matrix AOP框架进行切面架构…

天工开物 #6 Git 分支管理与版本发布

Git 版本管理系统由 Linux 的作者 Linus Torvalds 于 2005 年创造,至今不到二十年。 起初,Git 用于 Linux Kernel 的协同开发,用于替代不再提供免费许可的 BitKeeper 软件。随后,这一提供轻量级分支的分布式版本管理系统得到了开源…

产品经理被气的脸都绿了!

见字如面,我是军哥! 本来今天不想发文了,想躺平一下,毕竟今天周五了嘛。 可是今天早上一位买了我《技术人核心能力》的程序员学员发来私信,说他给产品经理上了一课,声称产品经理当时脸都绿了,并…

浅浅的理解MVI

MVI 的概念 官网解释: https://developer.android.google.cn/topic/architecture?hlzh-cn MVI在架构分层上和MVP没有本质区别,但区别主要体现在架构风格和编程思想上。 MVI 是 Model-View-Intent 的缩写,它也是一种响应式 流式处理思想的…

【Linux高级 I/O(2)】如何使用阻塞 I/O 与非阻塞 I/O?——select()函数

上次我们虽然使用非阻塞式 I/O 解决了阻塞式 I/O 情况下并发读取文件所出现的问题,但依然不够完美,使得程序的 CPU 占用率特别高。解决这个问题,就要用到本文将要介绍的 I/O 多路复用方法。 何为 I/O 多路复用 I/O 多路复用(IO m…

数据结构-时间复杂度和空间复杂度

时间复杂度和空间复杂度 算法效率时间复杂度空间复杂度表示方法(大O的线性表示)举例说明时间复杂度举例说明空间复杂度举例说明冒泡排序的时间和空间复杂度递归情况下的时间和空间复杂度两个例子 算法效率 算法(Algorithn)是指用来…

Spring MVC的核心类和注解

DispatcherServlet DispatcherServlet作用 DispatcherServlet是Spring MVC的核心类,也是Spring MVC的流程控制中心,也称为Spring MVC的前端控制器,它可以拦截客户端的请求。拦截客户端请求之后,DispatcherServlet会根据具体规则…

chatgpt赋能Python-python3接口自动化

Python3接口自动化:提升测试效率的利器 Python是一种高级编程语言,广泛应用于Web开发、数据科学、机器学习等领域。近年来,Python在接口自动化测试领域也变得越来越受欢迎。 Python的易读性、可扩展性以及模块化的特性,使得它成为…

Elasticsearch环境搭建(Windows)

一、介绍 布式、RESTful 风格的搜索和分析。 Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana 使您能够以交互方式探索、可视化和分享对数据的见解,并管…

手撕code(1)—— 排序算法

文章目录 前言1 冒泡排序2 选择排序3 插入排序4 快速排序5 归并排序6 堆排序7 希尔排序 前言 算法动画 时间复杂度分析 从小到大排序 1 冒泡排序 被动的将最大值送到最右边 1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。 2、对每一对相邻元素作同…

Vite+Vue+iClient for Leaflet引入并实现MapV/Eharts第三方可视化库示例

作者:gaogy 文章目录 背景一、使用Vite构建Vue3JavaScript项目二、搭建iClient for Leaflet开发环境三、第三方可视化库Echarts的使用四、第三方可视化库MapV的使用五、其他地图库 背景 最近很多小伙伴咨询关于基于Vue3框架搭建iClent开发环境并使用Echarts与MapV等…