华为云CodeArts Pipeline流水线对接使用全攻略:从零搭建云原生CI/CD
1. 认识CodeArts Pipeline:云原生时代的流水线引擎
在软件交付的DevOps实践中,流水线是连接代码变更到生产部署的核心纽带。华为云CodeArts Pipeline作为一款可视化的自动化任务调度平台,将编译构建、代码检查、测试计划、部署等众多服务的能力串联起来,形成一条从代码提交到上线发布的自动化高速公路。与传统的自建Jenkins方案相比,CodeArts Pipeline提供了免运维的云原生托管体验、内置的Maven依赖缓存加速、原生Kubernetes集群集成以及开箱即用的代码检查工具,将构建时间从平均15分钟缩短至4分钟,同时彻底消除了Jenkins服务器维护和插件兼容性等运维负担。
CodeArts Pipeline的本质是一个可视化的任务编排与调度平台,用户可以根据业务需要,将不同类型的自动化任务按阶段进行编排,配置串行或并行的执行关系,一次配置完成后即可一键触发或自动触发执行。无论是开发测试环境的快速验证,还是生产环境的灰度发布,CodeArts Pipeline都能提供灵活高效的流水线支撑。
需要先登录华为云控制台,点击:华为云控制台,还没有账号,点击:注册并关联,已有账号点击:登录后关联
2. 对接前的准备工作
在开始使用CodeArts Pipeline之前,需要完成一系列前置准备工作,这些步骤是流水线能够正常运行的基础。
2.1 开通并授权使用CodeArts Pipeline
使用CodeArts Pipeline前,需要先订阅CodeArts套餐。登录华为云控制台后,在服务列表中选择"开发与运维 > 流水线 CodeArts Pipeline",单击"立即使用"即可进入流水线服务首页。如果是首次使用,系统会引导完成服务的开通授权。
权限管理方面,建议使用租户账号或具有足够权限的子账号进行操作。通过统一身份认证服务(IAM),可以为不同角色的用户授予不同的操作权限。CodeArts Pipeline提供了四个预置策略,涵盖了从只读到完全控制的不同权限级别,企业可以根据实际需要为用户组分配相应的权限。
2.2 创建CodeArts项目
流水线是归属于具体项目的资源,因此在创建流水线之前必须先有一个CodeArts项目。在CodeArts首页单击"新建项目",可以选择Scrum、看板等不同的项目模板。以Scrum模板为例,输入项目名称(如"Project01")后单击确定即可完成项目创建。项目创建后,所有的代码仓库、构建任务、部署应用和流水线都将在这个项目下进行统一管理。
2.3 准备代码仓库
CodeArts Pipeline支持多种代码仓库作为流水线源,包括CodeArts Repo(华为云自带的代码托管服务)、GitCode、GitHub、GitLab、Bitbucket等。如果使用CodeArts Repo,需要在项目中新建代码仓库。进入代码托管页面,填写仓库名称(如"Repo01")并选择模板(如Java Maven Demo),即可快速创建一个包含示例代码的仓库。值得注意的是,新建代码仓库时会自动创建同名的代码检查任务,方便后续在流水线中直接引用。
对于第三方代码仓库(如GitHub、GitLab),需要通过服务扩展点来实现与CodeArts Pipeline的连接。服务扩展点本质上是一种凭证管理机制,用于提升代码库的操作权限或连接非CodeArts的第三方代码库。在新建流水线时,可以选择已创建的服务扩展点,也可以单击"新建服务扩展点"进行创建。
2.4 准备构建与部署资源
流水线的核心任务是串联构建和部署。在编译构建服务中,需要新建构建任务(如"BuildTask01"),选择代码源(Repo)、代码仓库和默认分支(master),然后选择合适的构建模板(如Maven系统模板)。部署方面,需要新建主机集群并将目标主机加入集群,然后在部署服务中新建部署应用(如"DeployTask01"),选择空白模板,添加"选择部署来源"步骤,配置源类型为"构建任务",并指定下载到主机的部署目录。这些构建和部署任务将在后续的流水线编排中被引用。
3. 新建流水线:图形化与YAML化双轨并行
CodeArts Pipeline提供了两种流水线创建方式:图形化编排和YAML化编排,分别适用于不同场景和用户偏好。
3.1 图形化编排:所见即所得的流水线配置
图形化编排是CodeArts Pipeline的默认创建方式,通过拖拽和配置界面,用户可以直观地看到任务的串并行关系。新建流水线的步骤如下:
第一步,访问流水线服务首页,单击"新建流水线",进入基本信息配置页面。需要配置以下关键信息:
- 名称:流水线的自定义名称,支持中文、大小写英文字母、数字、中划线和下划线,长度不超过128个字符。
- 委托URN:IAM委托的唯一标识,配置后流水线执行时使用委托身份和权限访问其他云服务,否则使用执行人的身份和权限。
- 所属项目:流水线归属的项目,从项目入口新建时默认为当前项目。
- 流水线源:选择代码源类型(Repo、GitHub等),如果不需要关联代码仓也可以选择"暂不选择"。
- 代码仓与默认分支:选择具体的代码仓库和分支。
- 服务扩展点:关联第三方代码源时使用。
- 别名:设置后可基于别名生成仓库对应的系统参数,便于在流水线中引用。
第二步,选择模板。CodeArts Pipeline提供了丰富的系统模板(如Maven构建部署模板、Node.js模板等),也支持自定义模板。用户可以选择合适的模板快速生成流水线,也可以选择"空模板"从零开始构建。
第三步,进入任务编排页面。系统默认生成"流水线源"和"阶段_1"两个阶段。用户可以根据需要新增阶段、添加任务、配置串并行关系。每个阶段可以包含多个任务,任务之间可以串行执行(按顺序)或并行执行(同时进行)。
3.2 YAML化编排:代码化流水线
YAML化编排适合需要批量配置多条流水线、希望将流水线配置纳入版本控制的场景。YAML化流水线仅支持使用CodeArts Repo代码仓。YAML文件通常由触发方式(on)、参数(env)、任务(jobs)等核心部分组成。
以下是一个典型的YAML流水线示例,展示如何串联编译构建、代码检查和部署三个任务:
env:
image_version: 1.0.0
jobs:
build:
name: maven build
steps:
- name: My build step
uses: CodeArtsBuild
with:
jobId: 878b4d13cb284d9e8f33f988a902f57c
artifactIdentifier: my_image
version: ${{ env.image_version }}
check:
name: code check
steps:
- name: My check step
uses: CodeArtsCheck
with:
jobId: 43885d46e13d4bf583d3a648e9b39d1e
checkMode: full
deploy:
name: cce deploy
needs:
- build
- check
if: ${{ completed() }}
steps:
- name: My deploy step
uses: CodeArtsDeploy
with:
jobId: 9c5a5cda6ffa4ab583380f5a014b2b31
version: ${{ env.image_version }}在这个示例中,env区域定义了环境变量image_version,可以在流水线的任意任务中引用。jobs区域定义了三个任务:build(编译构建)、check(代码检查)和deploy(部署)。deploy任务通过needs字段声明依赖于build和check两个任务完成之后才执行。if: ${{ completed() }}表示只有当所有依赖任务都完成时才运行部署。uses字段指定了使用的插件(CodeArtsBuild、CodeArtsCheck、CodeArtsDeploy),with字段传递插件运行参数。
新建YAML流水线时,可以在新建过程中创建一个新的YAML文件,也可以提前编排好YAML文件后直接导入。
4. 流水线核心编排:阶段、任务与插件
流水线的编排是使用CodeArts Pipeline的核心环节,涉及阶段管理、任务配置和插件使用三个层面。
4.1 阶段:业务流程的分类管理
阶段(Stage)是流水线上的基本组成部分,主要用于对任务做业务流程上的分类编排管理。每个阶段都有明确的输入、处理逻辑和输出,按照一定的顺序依次执行。一条流水线最多可配置16个阶段。
阶段的配置包括以下几个方面:
- 编辑阶段:可以配置阶段名称和"总是运行"属性。选择"是"表示流水线执行时该阶段下的任务默认选中且不可取消;选择"否"则表示任务默认选中但可以取消。
- 复制与删除:支持复制现有阶段或删除不需要的阶段。
- 排序:通过拖拽可以调整阶段的执行顺序。
- 阶段准入:控制流水线阶段的执行方式,包括自动(流水线执行时自动进入下一阶段)、手动(需手动确认后才能进入下一阶段)和时间窗(需在配置的时间段内才能执行)三种类型。
4.2 任务:流水线的最小执行单元
任务是流水线上可管理的最小执行单元,在阶段中进行纳管和编排。每个任务本质上对应一个具体的操作,如代码检查、编译构建、部署等。在"任务编排"页面,单击阶段下的"新建任务",可以选择"从空任务新建"或"从模板新建"。
任务编排的核心是配置插件。CodeArts Pipeline提供了五大类插件:构建插件、代码检查插件、部署插件、测试插件和通用插件。将鼠标移动到插件卡片上单击"添加",即可将插件添加到任务中。配置插件时需要填写插件名称、选择需要调用的任务(支持搜索过滤),如果调用的任务有参数,参数也会显示出来供配置。
任务之间可以建立串行或并行的关系:
- 串行编排:单击任务下方的添加按钮,可以添加一个和该任务按顺序执行的任务,适用于有依赖关系的场景(如先构建后部署)。
- 并行编排:单击"并行任务",可以添加一个和已有任务同时执行的任务,适用于可以独立运行的任务(如代码检查和构建可以同时进行)。
值得注意的是,单个任务中最多只能添加一个带"任务"标记的插件。"挂起流水线"插件只能添加在不含并行任务的阶段中。
4.3 插件:扩展流水线能力的生态
插件是流水线能力扩展的核心机制。除了CodeArts内置的构建、检查、部署、测试插件外,用户还可以开发自定义插件来满足特定需求。
以"Build构建"插件为例,其核心参数包括:
- 名称:插件在流水线中显示的名称。
- 项目配置:可选择本项目或其他项目,选择"其他项目"时需要指定具体的项目。
- 请选择需要调用的任务:选择本项目下或其他项目下的构建任务。
- 产物标识:用于标识构建产物,后续任务可以通过${{ jobs.任务ID.artifacts.产物标识 }}的方式获取产物信息。
在YAML化流水线中,Build构建插件的配置语法如下:
uses: CodeArtsBuild
with:
jobId: 878b4d13cb284d9e8f33f988a902f57c
artifactIdentifier: my_pkg
customParam: value其中jobId是编译构建任务的ID,可在构建任务详情页的浏览器URL末尾获取(32位数字字母组合)。
对于需要调用第三方API的场景,CodeArts Pipeline提供了"第三方接口调用v2"插件,支持配置Web API调用。需要注意的是,此插件需要证书校验,不支持自定义证书和无证书校验。
5. 流水线参数:实现任务间数据流动
流水线参数是流水线运行过程中使用的可配置值,用于控制流水线的行为、流程和输出结果。通过参数,可以实现构建、部署、测试等任务之间的数据拉通,只需配置好流水线参数,即可完成多任务的数据传递。
5.1 参数类型
CodeArts Pipeline支持三种类型的参数:
- 系统预定义参数:系统默认提供的参数,无需定义、不能删除、不能修改。包括项目ID(PROJECT_ID)、流水线ID(PIPELINE_ID)、执行编号(PIPELINE_NUMBER)、提交ID(COMMIT_ID)、执行时间戳(TIMESTAMP)、触发类型(PIPELINE_TRIGGER_TYPE)等数十个参数。在参数输入框输入"$"符号后会自动出现系统预定义参数列表供选择。
- 自定义参数:用户根据需要自定义添加,类型包括字符串类型、枚举类型、自增长类型。最多可以新建100个自定义参数。
- 通用参数组:项目下的通用流水线参数,所有流水线都可以关联并使用。最多可以新建5个通用参数组,每个参数组最多可以添加100个自定义参数。
5.2 参数优先级与引用
当存在同名参数时,优先级为:系统预定义参数 > 自定义参数 > 通用参数组。当同一条流水线关联多个参数组且存在同名参数时,以最后关联的参数组的参数值为准。
参数的引用形式为${参数名}。在图形化编排中,可以在任务配置界面的参数输入框中直接引用;在YAML化编排中,通过${{ env.参数名 }}的方式引用。
5.3 实战:通过流水线参数串联构建与部署
以下通过一个完整的示例说明流水线参数的传递机制。假设我们需要在构建时指定版本号,并在部署时使用该版本号的软件包:
第一步,在编译构建任务中新建一个名为"releaseversion"的参数,并打开"运行时设置"开关。这样在流水线触发时就可以动态传入版本号。
第二步,在部署任务中新建软件包参数,引用构建任务产出的软件包。
第三步,在流水线中新建一个版本号参数(如"version"),类型选择字符串,并设置为运行时参数。然后在流水线的构建任务中,将构建任务的releaseversion参数引用流水线的version参数;在部署任务中,将软件包参数也引用流水线的version参数。
第四步,执行流水线时,在弹出的执行配置窗口中输入version的值(如1.0.1),流水线会自动将这个值传递给构建任务和部署任务。构建任务使用该版本号构建出对应版本的软件包,部署任务则获取该版本的软件包进行部署。
这种方式确保了构建和部署使用的软件包版本完全一致,避免了手动配置可能导致的不一致问题。
6. 执行计划:让流水线自动跑起来
CodeArts Pipeline支持四种执行计划:事件触发、定时任务、并发策略和抢占策略。
6.1 事件触发
事件触发包括代码提交时触发、合并请求时触发、创建标签时触发三种类型。配置事件触发时,可以指定触发条件:
- 先匹配分支,再匹配路径,两者都匹配成功才触发流水线。
- 路径排除优先于路径包含。如果变更文件没有全部在排除范围内,则继续匹配包含的路径。若未配置包含路径则匹配成功;若配置了包含路径且变更文件在排除范围外有任意一个在包含范围内,则匹配成功。
- 标签排除优先于标签包含,标签同时在包含和排除中时匹配失败。
路径匹配范围限制为单次提交的前300个变更文件,超过300个变更文件建议拆分提交。
6.2 定时任务
定时任务支持配置流水线在指定的时间自动执行。配置时需要指定执行日期、时间段(含时区)、间隔时间以及执行方案。最多可以设置10个定时任务。
定时任务的典型应用场景包括:每日凌晨自动构建并部署到测试环境、每周定期执行全量代码检查等。
6.3 并发策略与抢占策略
默认情况下,单条流水线最大执行并发数为5。通过并发策略可以更细粒度地控制并发资源:
- 并发个数:设置单条流水线同时处于运行中和暂停状态的最大实例数,受套餐和购买并发数限制。
- 超过并发后执行策略:可选择"排队等待"(新触发排队等待,最多支持100条排队记录,排队超过24小时后被放弃)或"忽略不执行"(新触发直接忽略)。
抢占策略允许新触发的运行实例强行停止当前流水线中相同事件触发的其他所有运行实例。这在紧急修复场景下非常有用,可以确保最新的变更优先得到构建和部署。
7. 执行与监控:实时掌握流水线状态
流水线支持一键执行,执行过程可视化,可实时查看执行进度、日志和结果。
7.1 执行流水线
在流水线列表页找到待执行的流水线,单击操作列的执行按钮,弹出"执行配置"窗口。配置内容包括:
- 代码源:选择分支或Tag。
- 运行参数配置:如果流水线配置了运行时参数,在此设置参数值。
- 执行阶段配置:可以选择只执行部分任务(默认执行全部)。配置了"总是运行"的阶段任务默认选中且不可取消。
- 执行描述:填写本次执行的信息说明。
7.2 执行过程操作
在流水线详情页面,用户可以进行以下操作:
- 重试:在失败任务处重新执行。
- 停止:中止正在执行的任务。
- 重新执行:按照当前配置重新执行整条流水线。
- 编辑:修改流水线的配置信息。
7.3 审计与日志
CodeArts Pipeline集成了云审计服务(CTS),可以记录流水线相关的操作事件,便于日后的查询、审计和回溯。云审计服务管理控制台保存最近7天的操作记录。
执行完成后,可以在流水线详情页查看每个任务的执行日志和结果。执行过程遇到的问题可以参考流水线常见问题文档进行排查。
8. 权限管理:精细化控制流水线访问
CodeArts Pipeline的权限管理基于IAM和项目级权限两层体系。
8.1 IAM权限
通过统一身份认证服务,可以为用户组授予流水线服务的操作权限。在IAM控制台的用户组授权页面,选择"流水线服务",可以看到四个预置策略:
- 流水线服务只读权限:允许查看流水线列表和详情,但不能进行创建、编辑、执行等操作。
- 流水线服务操作权限:允许创建、编辑、执行流水线。
- 流水线服务管理员权限:允许所有操作,包括删除流水线、管理权限等。
- 流水线服务策略管理权限:允许管理流水线的策略和规则。
8.2 项目级权限
在CodeArts项目层面,流水线的权限与项目角色关联。项目管理员和流水线创建者拥有编排流水线阶段和任务的权限。执行流水线需要用户角色为项目管理员或流水线创建者。
此外,流水线还支持单任务角色权限配置,可以针对流水线中的单个任务设置特定的执行权限。
9. 进阶能力:准出条件与扩展插件
9.1 准出条件:质量门禁自动化
准出条件(Quality Gate)是流水线阶段中配置的质量指标卡点,通过规则和策略的配合,实现阶段准出校验并最终控制流水线的执行。
- 规则:基于扩展插件的输出阈值,设置比较关系和阈值条件。例如,可以设置代码检查的缺陷数不能超过10个。
- 策略:一系列规则的集合,每个规则对应一个步骤插件的输出指标值的条件模板。通过预定义策略,可以很方便地在多条不同流水线中应用同样的准出条件。
准出条件只对当前阶段有效,同一阶段中可以配置多个不同的准出条件。规则与策略功能需要升级CodeArts套餐至基础版才可使用。
9.2 自定义扩展插件
除了使用CodeArts内置的插件外,用户还可以开发自定义插件来满足特定需求。自定义插件发布为草稿后,可以在流水线任务中引用。扩展插件的开发能力使得CodeArts Pipeline可以对接企业内部的各种系统,如审批系统、监控系统、通知系统等。
10. 实战案例:Maven项目从代码提交到自动部署
以下通过一个完整的Maven项目示例,展示从代码提交到自动部署到华为云CCE(云容器引擎)的全流程。
10.1 场景描述
假设有一个Java Maven项目,代码托管在CodeArts Repo中。需要实现:当代码推送到master分支时,自动触发流水线,完成代码检查、Maven编译构建、Docker镜像构建与推送、部署到CCE测试环境。
10.2 流水线编排
流水线包含以下阶段和任务:
- 阶段1:代码检查与构建
- 任务1:CodeArtsCheck(代码检查)
- 任务2:CodeArtsBuild(Maven构建 + Docker镜像构建)
- 阶段2:部署
- 任务1:CodeArtsDeploy(部署到CCE)
阶段1中的两个任务可以并行执行,提高效率。阶段2在阶段1完成后自动执行(准入类型设置为"自动")。
10.3 YAML化流水线配置
对应的YAML配置文件如下:
env:
image_tag: latest
namespace: test
jobs:
code_check:
name: 代码检查
steps:
- name: 执行代码检查
uses: CodeArtsCheck
with:
jobId: 43885d46e13d4bf583d3a648e9b39d1e
checkMode: full
build:
name: 构建与镜像打包
steps:
- name: Maven构建并推送镜像
uses: CodeArtsBuild
with:
jobId: 878b4d13cb284d9e8f33f988a902f57c
artifactIdentifier: my_app
dockerImage: swr.cn-north-4.myhuaweicloud.com/myproject/myapp:${{ env.image_tag }}
deploy:
name: 部署到CCE
needs:
- code_check
- build
if: ${{ success() }}
steps:
- name: 部署到测试环境
uses: CodeArtsDeploy
with:
jobId: 9c5a5cda6ffa4ab583380f5a014b2b31
cluster: cce-test-cluster
namespace: ${{ env.namespace }}
image: swr.cn-north-4.myhuaweicloud.com/myproject/myapp:${{ env.image_tag }}10.4 执行计划配置
在"执行计划"页面配置事件触发:勾选"代码提交时触发",分支选择master。这样每次代码推送到master分支时,流水线就会自动执行。
10.5 执行与验证
当开发者推送代码到master分支后,流水线自动触发。可以在流水线详情页实时查看每个任务的执行进度和日志。构建成功后,镜像自动推送到SWR(容器镜像服务),部署任务将新镜像部署到CCE测试环境。整个流程从代码提交到服务更新完成,全程自动化,无需人工干预。
11. 与传统Jenkins的对比分析
对于已经熟悉Jenkins的团队,了解CodeArts Pipeline的优势有助于做出更合理的技术选型。
| 对比维度 | Jenkins | 华为云CodeArts Pipeline |
|---|---|---|
| 运维方式 | 自建服务器,需自行维护 | 云原生托管,免运维 |
| 可用性 | 依赖自建机房,无SLA保障 | 99.99%高可用 |
| Maven构建时间 | 约15分钟(含依赖下载) | 约4分钟(内置缓存加速) |
| Kubernetes集成 | 需安装K8s插件 | 原生支持CCE,零配置 |
| 代码检查 | 需配置SonarQube等工具 | 内置6种检查工具,开箱即用 |
| 部署策略 | 需编写脚本 | 内置滚动更新、灰度发布等模板 |
| 成本 | 服务器费用 + 运维人力 | 按构建时长计费,含免费额度 |
CodeArts Pipeline在运维成本、构建效率、云原生集成等方面具有明显优势,特别适合已经或计划将业务部署在华为云上的团队。
12. 常见问题与最佳实践
12.1 常见问题
问题1:流水线执行失败,提示找不到构建产物。 解决方案:检查构建任务的产物标识是否正确配置,以及在后续任务中引用产物时路径是否正确。在YAML化流水线中,确保artifactIdentifier与引用时保持一致。
问题2:事件触发不生效。 解决方案:检查分支和路径的匹配规则。注意路径排除优先于路径包含。另外确认代码仓库的Webhook配置是否正确。
问题3:并发执行时出现资源冲突。 解决方案:合理配置并发策略,根据套餐限制设置并发个数。对于需要独占资源的任务,可以考虑使用"抢占策略"。
12.2 最佳实践
- 参数化流水线:尽量将可变的配置(如版本号、环境名称)抽象为流水线参数,提高流水线的复用性。
- 分阶段设置准出条件:在测试阶段设置严格的代码质量门禁,在部署到生产环境前设置人工确认阶段。
- 利用通用参数组:对于项目中多条流水线共用的参数(如镜像仓库地址、通知邮箱),使用通用参数组统一管理。
- 合理使用缓存:CodeArts Build内置了Maven等构建工具的依赖缓存,充分利用可以大幅缩短构建时间。
- 监控与审计:开启云审计服务,定期查看流水线的执行记录和操作日志。
结语
华为云CodeArts Pipeline作为云原生的CI/CD流水线服务,通过可视化的编排能力、丰富的插件生态、灵活的触发机制和精细的权限管理,为企业提供了高效、可靠的持续交付解决方案。从简单的代码检查到复杂的多环境灰度发布,CodeArts Pipeline都能够提供有力的支撑。通过本文的系统讲解和实战示例,相信读者已经掌握了CodeArts Pipeline的核心对接使用方法,可以开始在项目中实践云原生的DevOps流水线了。
常见问答
问1:CodeArts Pipeline和Jenkins相比,最大的优势是什么?
答:CodeArts Pipeline最大的优势在于免运维和云原生集成。用户无需关心服务器的维护、插件兼容性等问题,同时原生支持华为云CCE、SWR等服务,内置Maven依赖缓存加速,构建效率显著提升。
问2:图形化编排和YAML化编排应该怎么选择?
答:图形化编排适合初学者和需要快速搭建流水线的场景,界面直观、操作简单。YAML化编排适合需要批量管理多条流水线、希望将流水线配置纳入版本控制的团队。两者可以结合使用,根据具体场景灵活选择。
问3:流水线参数如何在不同任务之间传递?
答:在图形化编排中,通过${参数名}的方式引用;在YAML化编排中,通过${{ env.参数名 }}的方式引用。参数优先级为:系统预定义参数 > 自定义参数 > 通用参数组。
问4:如何实现代码提交后自动触发流水线?
答:在流水线的"执行计划"页面配置事件触发,勾选"代码提交时触发"并指定分支。可以进一步配置路径过滤,只有特定目录下的文件变更时才触发。
问5:流水线执行失败后如何快速恢复?
答:在流水线详情页,可以在失败任务处单击"重试"重新执行该任务;也可以单击"重新执行"按照当前配置重新执行整条流水线。如果是由于配置问题导致的失败,可以单击"编辑"修改流水线配置。
问6:CodeArts Pipeline支持哪些代码仓库?
答:支持CodeArts Repo(华为云原生)、GitCode、GitHub、GitLab、Bitbucket等多种代码仓库。对于第三方代码仓库,需要通过服务扩展点进行连接。


