版本修订

版本修订历史
版本 作者 时间 描述

0.22

Lang

2024-04-08

提醒模块文档(站内信功能)

0.21

Lang

2023-11-13

前端命名语义

0.20

Lang

2023-11-09

2.0版本文档

0.19

Lang

2023-10-25

工作流功能升级

0.18

Lang

2023-09-07

自定义表单、办公协同(ONLYOFFICE)

0.17

Lang

2023-09-04

列操作定制

0.16

Lang

2023-08-29

上传/下载详解

0.15

Lang

2023-08-15

CRUD实战

0.14

Lang

2023-07-20

前端基础教程

0.13

Lang

2023-06-04

AOP分流器文档

0.12

Lang

2023-05-02

Agreed Metadata Specification

0.11

Lang

2023-04-17

前端基础

0.10

Lang

2023-03-26

附件、文档管理

0.09

Lang

2023-03-23

工作流引擎配置

0.08

Lang

2023-03-22

Zero Extension详细介绍

0.07

Lang

2023-03-20

模块化配置/文档修订

0.06

Lang

2023-03-16

Qr查询引擎(前后端)

0.05

Lang

2023-03-11

配置/实施规范中的权限管理

0.04

Lang

2023-02-22

前端样式规范补充

0.03

Lang

2023-02-14

前端结构规范补充

0.02

Lang

2023-02-12

动态建模平台一键式部署修订

0.01

Lang

2023-02-07

起草基本云平台规范

Chapter I: 环境标准

1. 飞翼零式

1.1. 时间线

1.1.1. 发展轨迹

Zero框架整体发展时间轴如下:

0

1.1.2. 项目结构

新版Zero整体结构如:

项目 说明

zero-ecotope

根项目:POM管理、版本管理、文档管理。

zero-epic

内含 AMS(Agreed Metadata Specification)接口设计和规范定义,作为最底层跨框架基础功能规范。

zero-elite

原 Zero Core 核心框架,包含内置组件、功能函数、编排器,为上层容器提供环境支撑,新版还引入了OSGI规范。

zero-energy

Web容器,可选择三种方式运行:单机运行、OSGI插件运行、云环境运行。

zero-equip

Infix Architecture 的各种功能插件,对应旧版 Zero Infix。

zero-extension

Zero Extension 扩展插件,对应旧版 Zero Extension。

zero-external

动态建模专用外置插件,如 Oracle、MySQL 等,基于 MBSE 的核心插件体系。

zero-entry

入口程序,可选择:最小环境运行、单点脚手架环境、继承专用POM库。

1.2. 设计哲学

如何打造一个零开发、零测试、零运维的系统?也许未来就来了、也许永远都做不到。

作者吐槽:本章节有打广告的嫌疑!

1.2.1. 均衡工作量

面相开发、测试、运维的均衡工作量框架。

一个系统从开发到最终上线落地,Zero秉承均衡 开发、测试、运维 三大主体角色工作量的核心理念,解决企业在交付项目过程中开发人员只关注于交付的陋习,软件工程本质是以 工程 为目的体系化解决方案,根据实战经验,让开发人员把目光聚焦到:快速交付、工程实战 上,并非以 编程 为中心的战场。从之前项目的经验可以知道,运开测是最注重团队模式的三个点,传统开发模式中重开发,轻测试、运维,很多工程师都抱怨开发不管不顾,到最后形成 运维、测试、二开 的灾难(这种形态在大量中小型企业中比比皆是)。

1.2.2. 建模为主

以建模为主战场的技术框架。

Zero最新版基于 MBSE 理论,以建模为中心打造稳定、可成长、自管理的系统(已渗透到工业领域)。Zero从最早的版本中 代码驱动、到 CMDB 产品的 配置驱动、以及最新版的 数据驱动,整个过程都在强调一个主题:建模。一个完整的系统,模型是设计最复杂的部分,也是抽象层次最高的实现部分,目前Zero已经可以支持多种不同的建模方式(静态建模、混合建模、动态建模),也为企业应用、平台应用、工业应用提供了基础土壤,本教程中所有的开发技能、实战经验都围绕建模展开。

1.2.3. 成长型系统

一个无痛迁移、升级、扩展的柔性框架。

为什么均衡运开测三个角色,因为很多时候开发人员缺了一个执念:所有交付的项目、产品都只是一个过程形态,并非最终形态,那些交付了不再改的系统只是自我安慰罢了。 所以 Zero 框架的设计中很重头戏的一部分是面向各种不同的业务需求变化,您可以说它不是一个纯技术框架,但从目前交付的项目看起来,它拥有着面向新需求快速交付实施的基础。不论是内部框架标准化、外部集成标准化,所有的努力实际都在将目前固化的软件模式、设计范式抽象出来形成标准化模块以驱动后续新业务的扩展。

1.2.4. 数字化体系

以制度、流程、规范、工具为核心的体系化框架。

数字化转型对中小企而言,更多场景并非直接复制大公司的成熟解决方案,而是要基于自身的土壤打造符合企业自身发展的合理的解决方案,如何降低企业在营运过程中的成本,提高管理效率才是真正意义上的体系化解决方案,工具只是其中一部分(包括 Zero 打造的系统也只是整个闭环中的一个阶段)。但是工具要为管理赋能,一些待验证的策略、想法都属于 在路上 的状态,那么如何使用一个工具去帮助企业快速、小成本验证这一切,并对企业提出相关整改项,也是Zero的硬核部分,目前Zero在银行、证券领域中的应用就在扮演这样一个角色,配合制度、规范、流程的落地。

2. 环境要求

最新版本中,核心框架的 zero-epic(原 vertx-co) 已经将底层规范项目分离成新的 zero-ams 项目,该项目可在任意 Vert.x 相关的项目中使用,全称为 Agreed Metadata Specification,意在打造以 建模 / 工具 为中心的基础规范项目底座,并使用SPI实现了从 Vert.x 到 Spring 以及其他框架的无缝切换,该项目完整版将在 1.0 正式版本发布中问世,增强了通用性和扩展性,大量开放出来的代码结构和规范都来自于现阶段的 Vert.x/Zero 项目中。

2.1. 默认HOST

Zero框架中为了方便远程本地协同开发,以及各个团队成员之间协同开发不牵涉配置文件的冲突修改,您可以优先在开发环境(包括生产环境)中配置如下域名映射:

域名 默认地址 含义

ox.engine.cn

127.0.0.1

数据库访问专用地址

ox.macrocosm.cn

127.0.0.1

后端专用地址(目前版本后端地址使用的是 ox.engine.cn)

ox.server.cn

127.0.0.1

前端专用地址

ox.integration.cn

127.0.0.1

(保留)集成配置专用地址

ox.office.cn

127.0.0.1

文档服务器 地址( ONLYOFFICE )专用

2.2. 后端开发

分类 版本 执行命令 用途

运行时

17+

java

下载,Java环境

运行时

3.2.0

ruby, gem

下载,推荐AsciiDoc使用Ruby方式安装

运行时

2.37.1+

git

下载,MacOS中XCode自带

运行时

6.5

tiup

下载,TiDB命令

2.3. 前端开发

分类 版本 执行命令 用途

运行时

20+

node, npm

下载,NodeJS环境

构建

1.22.19

yarn

(npm)直接安装,前端主构建工具

构建

5.75.0

webpack

略

框架

5.2.0

-

Ant Design主界面库

框架

2.3.54

-

Ant Design Pro企业框架主库

框架

4.2.9

-

Ant G2图表库

框架

2.3.0

-

Ant G6拓扑图、树图、脑图库

框架

11.3.1

-

BPMN工作流前端专用库

框架

18.2.0

-

React主框架库

框架

6.8.1

-

React-Router专用库

框架

16.0.1

-

React Dnd拖拽主库

运行Zero UI请将Chrome浏览器升级到最新版 110+ 以确认样式文件生效,根据部署经验,老版本在使用过程中样式会有一定问题。

2.4. 运维部署

分类 版本 执行命令 用途

构建

3.8.x+

mvn

下载,Maven环境

构建

1.0.0-m4

mvnd

下载,并行Maven环境(自带Maven 4.0)

构建

7.6+

gradle

下载,Gradle环境

容器:运行时

20.x

docker, docker-compose

下载,容器运行时,新版自带K8S单节点集群环境

容器:镜像工具

1.8.5

packer

下载,镜像工具,Maven可使用插件直接打包镜像

自动部署

2.14.2

ansible

下载,应用配置自动部署工具

自动部署

1.3.7

terraform

下载,基础设施自动部署工具

2.5. 文档管理

分类 版本 执行命令 用途

文档

4.0.x

jsdoc

(npm/yarn)JavaScript文档生成

文档

1.2.2

live-server

(npm/yarn)文档服务器

文档

-

dash

(npm/yarn)标准文档皮肤工具

文档

2.0.18

asciidoctor

(gem)AsciiDoc文档生成工具

3. 流程管理

3.1. 开发流程

3.1.1. 流程图

开发流程走开源社区普遍的Fork流程,整体流程图如下:

Fork

整个环境中包括两种PR

  • Dev PR / develop分支:从开发人员Fork分支中直接提交PR到 develop 分支的PR,develop 分支可配置到测试环境中直接提供给测试人员测试。

  • Release PR / master分支:从 develop 分支提交同库PR到 master 分支中。

develop 分支和 master 分支追加保护功能,锁定之后不允许任何形式的 push 动作直接修改分支中的内容,仅走PR流程可更改两个分支中的代码。

3.1.2. 操作步骤

操作流程参考如下步骤:

  1. 在远程环境创建Fork(手工操作),Fork之后拿到自己的分支代码路径(如:https://gitee.com/account/xc.git)

  2. 使用git命令从远程个人账号中下载代码

    $ git clone https://gitee.com/account/xc.git
  3. 在本机项目中运行命令添加远程引用(引用名推荐:upstream):

    $ git remote add upstream https://gitee.com/silentbalanceyh/xc.git
  4. (上述三步执行完成后就搭建好了本地代码整体环境)提交代码流程:

    $ git add .
    $ git commit -m "您的备注信息"
    # 该步骤会提交代码到您自己的Fork分支:https://gitee.com/account/xc.git
    $ git push
  5. 代码提交之后可在线提交PR到 develop 分支中,Code Review之后执行合并。

  6. 更新代码流程:

    # 注意更新代码是从upstream中更新(develop分支):https://gitee.com/silentbalanceyh/xc.git
    $ git pull upstream develop
    
    # 此步骤的目的是保持最新代码推送到自己Fork分支中
    $ git push

3.2. 部署流程

3.2.1. 流程图

部署流程参考下图:

Fork

3.2.2. 关于IaC

IaC,全称为Infrastructure As Code(基础设施即代码),该术语在基础设施自动化时经常听到,它优势如下:

  1. 使用IaC,只需单击一下即可重新创建任何复杂的基础结构。

  2. 可以以IaC的形式对基础结构状态执行 版本控制。

  3. 以开发人员为中心的基础架构管理工作流程,和开发的应用程序一样,IaaC代码的标准做法是遵循所有标准编码实践(测试、审查等)。

整个工作流中同时使用ansible和terraform是不冲突的,前者负责 配置管理(应用配置管理),后者负责 基础设施(服务器、网络、虚拟机、数据库等),协同工作,再借用Jenkins工具做好DevOps的流水线工作,实现最终开发、测试、生产环境的自动化开发测试运维部署。

3.3. 发布管理

发布流程参考如下步骤:

3.3.1. 初始化数据库

如果新版本没有数据表结构的变化或者不需要清除数据,则不用进行 初始化数据库 的操作。

  1. 拉取最新代码到本地,运行 run-ansible.sh 文件执行本地数据库初始化。

  2. 将初始化完成的本地数据库导出(SQL格式,包含表和数据)。

  3. 将导出的数据库SQL文件复制到 ho-app/app@runtime/@backup 文件夹内。

  4. 修改 ho-app/run-env.sh 文件的 DB_ENV、DB_PASSWORD、DB_HOST 为发布的相关配置,参考如下:

    export DB_PASSWORD=*****
    export DB_ENV=PROD
    export DB_HOST=116.***.***.41
  5. 修改 init.database.sh、run-ansible.sh 文件中关于连接数据库的相关信息为服务器数据库的相关配置,如 数据库用户名、端口号 等等。

  6. 修改 init.playbook.yml ,将 DB_HOST 的值由 ox.engine.cn 改为 116.xxx.xxx.41 (此为服务器IP地址或域名)。

  7. 最后运行 run-ansible.sh 文件执行远程数据库初始化。

初始化成功的标志为远程数据库的表结构和数据与本地数据库保持一致。

3.3.2. 前端发布

  1. 修改 env.production 文件:Z_ENDPOINT=http://116.xxx.xxx.41:7085。

  2. 运行如下命令打包:

    yarn build
  3. 复制 build 文件夹到服务器的如下两个目录(如有 build 文件请删除后再复制进去):

    • /usr/local/nginx/html

    • /usr/local/share/nginx/html

如果没有可视化的工具复制 build 文件夹,可参考下面的命令。

# 先删除已经存在的build文件
cd /usr/local/nginx/html
sudo rm -rf build/
cd /usr/local/share/nginx/html
sudo rm -rf build/
# 复制build文件到指定路径(本机运行以下命令)
# 语法:scp [文件路径] [用户名]@[主机名]:[Linux目标路径]
scp -r /Users/dengchunmei/Desktop/XXX/hotel-ui/build root@116.xxx.xxx.41:/usr/local/nginx/html
scp -r /Users/dengchunmei/Desktop/XXX/hotel-ui/build root@116.xxx.xxx.41:/usr/local/share/nginx/html

3.3.3. 后端发布

  1. 粘贴复制以下代码到 ho-app目录的pom文件 。

       <!--                 docker打包部署插件       -->
                <plugin>
                    <groupId>com.google.cloud.tools</groupId>
                    <artifactId>jib-maven-plugin</artifactId>
                    <version>3.3.1</version>
                    <configuration>
                        <from>
                            <image>openjdk:17</image>
                        </from>
                        <to>
                            <image>registry.cn-hangzhou.aliyuncs.com/hotel-docker/hotel_docker</image>
                            <tags>
                                <tag>11.0</tag>
                            </tags>
                        </to>
                        <container>
                            <workingDirectory>/usr/local</workingDirectory>
                            <ports>
                                <port>7085</port>
                            </ports>
                            <mainClass>cn.vertxup.ZoAgent</mainClass>
                            <!--配置jvm虚拟机参数-->
                            <jvmFlags>
                                <jvmFlag>-Xms512m</jvmFlag>
                            </jvmFlags>
                            <environment>
                                <Z_HED_ENABLED>true</Z_HED_ENABLED>
                                <AEON_CLOUD>/Users/lang/zero-cloud/vertx-zero-cloud/</AEON_CLOUD>
                                <AEON_APP>/Users/lang/zero-cloud/cloud-hotel/</AEON_APP>
                                <Z_APP>app.micro.hotel</Z_APP>
                                <Z_API_HOST>0.0.0.0</Z_API_HOST>
                                <Z_CORS_DOMAIN>http://116.205.172.41:7005</Z_CORS_DOMAIN>
                                <Z_API_PORT>7085</Z_API_PORT>
                                <Z_HED_ENABLED>true</Z_HED_ENABLED>
                                <Z_DBS_HOST>116.xxx.172.41</Z_DBS_HOST>
                                <Z_DBW_HOST>116.xxx.172.41</Z_DBW_HOST>
                                <Z_DBH_HOST>116.xxx.172.41</Z_DBH_HOST>
                            </environment>
                        </container>
                        <allowInsecureRegistries>true</allowInsecureRegistries>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>build </goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
  2. 修改 vertx-detect.yml 文件里面数据库的配置为服务器数据库的相关配置,包含 端口号 和 IP地址 。

  3. 进入 hotel(项目根目录) ,运行以下命令验证阿里云镜像仓库(第一次发布时需要)。

    # 运行下述命令之后需要输入密码
    docker login --username=aliyun9950000555 registry.cn-hangzhou.aliyuncs.com
  4. 进入 ho-app ,运行以下命令打包。

    mvn clean compile jib:build
  5. 进入服务器,执行以下命令将原有容器和镜像删除:

    docker stop hotel # 停止运行hotel容器
    docker rm hotel # 删除hotel容器
    docker images # 查询镜像
    docker rmi <hotel镜像ID> # 删除hotel镜像
  6. 执行以下命令发布后端。

    docker run -d -p 7085:7085 --name hotel registry.cn-hangzhou.aliyuncs.com/hotel-docker/hotel_docker:11.0
  • 如果在执行上面最后一条命令的时候出现了不能找到镜像的错误,则需要按照第3步验证阿里云镜像仓库,之后再执行上述命令即可。

  • 最后一条命令的 11.0 需与第1步 pom文件 中的 <tag> 设置保持一致。

  • 运行起来之后可通过以下命令查看运行是否报错。

docker logs hotel

3.4. BUG提交

3.4.1. 入口

BUG管理主要牵涉开发模式,整体规范如下:

  1. 所有公共模块的问题提交到:https://gitee.com/silentbalanceyh/scaffold-zero/issues 中

  2. 各自应用现存的所有BUG放到自己公司的企业库中。

3.4.2. 模板说明

BUG问题模板如下:

0

  1. 重现步骤有截图最好带上截图提交

  2. 问题集中,主要牵涉:

    • 启用安全模块之后的账号信息提供

    • 前端界面入口

    • 牵涉到 模型 部分的提供模型的分类和统一标识符

  3. 其他的文本部分随意。

3.4.3. 标签

0

问题标签按Zero核心产品线进行分类,除 任务 和 培训 以外,其他内容最好都加上标签方便解决。

标签 关联站点 描述

zero-framework

http://www.zerows.io

核心框架问题

zero-extension

同上

扩展框架问题

zero-cloud

http://www.vertx-cloud.cn

云原生工具箱问题

zero-ui

http://www.vertx-ui.cn

前端框架问题

zero-ai

http://www.vertx-ai.cn

自动化脚本问题

4. 项目初始化

4.1. 自动化创建

4.1.1. Zero Ai安装

初始化工程之前先安装 Zero Ai工具,该工具提供了不同初始化工程的命令,可一键生成模板。

# 旧版
$ sudo npm install -g vertx-ai
# 新版
$ sudo npm install -g zero-ai

初始化完成之后既可执行工程初始化命令分别初始化:后端、前端、后端插件(现阶段只支持三种类型)。

4.1.2. Ai工具初始化

您可以直接下载 scaffold-zero 后端工程脚手架项目,然后手工修改。 也可以直接运行下边命令进行后端工程初始化:

# n=参数代表后端工程名称以及目录名称
# 请选择不带 `.git` 或 `scaffold-zero` 的目录执行当前命令,最好使用空目录
$ aj init -n <name>

您可以直接下载 scaffold-ui 前端工程脚手架项目,然后手工修改。 也可以直接运行下边命令进行前端工程初始化:

# n=参数代表前端工程名称以及目录名称
# 请选择不带 `.git` 或 `scaffold-ui` 的目录执行当前命令,最好使用空目录
$ ai init -n <name>

后端插件初始化执行运行下边命令:

# m=模块名称,c=配置文件路径,p=工作路径
# -c 和 -p 两个参数可选
$ aj plugin -m <name> -c <workspace.json> -p <path>

4.1.3. Cloud工具集

您可以自己搭建云端开发环境,也可直接下载 Cloud工具箱 云端工具包执行云端工程的辅助开发。

$ git clone git@gitee.com:silentbalanceyh/vertx-zero-cloud.git

推荐您先下载 Cloud工具箱,其中包含了很多一键式自动化脚本以及云端开发的专用目录结构,本文后续章节全部依托该项目执行相关命令。Zero Cloud核心规范全部位于地址 Zero Aeon Cloud专用数据规范,该站点中包含了所有针对配置数据、定义的配置描述,系统可依赖它做配置、模型、定义以及元数据的各种校验。

Cloud在部署基础设施(Docker Compose模式)时,有三个脚本文件:

文件后缀(不带扩展) 含义

@up

执行docker-compose up -d

@down

执行docker-compose down

@stop

执行docker-compose stop

4.2. Ansible环境初始化

4.2.1. 基本步骤

新版Zero使用了Ansible为开发人员准备一致性开发环境,但基础准备工作需要在此处特殊说明,开发环境的Ansible执行流程图如下:

Fork

Ansible基本准备工作如下:

  1. 目标机器(开发环境本地,生产环境服务器)需配置三个核心命令:mysql、mvn、java(开发环境初始化只需要mysql,java、mvn为将来准备着)。

  2. 由于Ansible使用登录方式为Non Shell,所以上述三个核心命令的配置需要配置在目标机器的 ~/.bashrc 环境变量文件中,如:

    # Ansible ------------------------------------------------------------------
    # Ansible Java
    export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
    export CLASSPATH=.
    export PATH=$PATH:$JAVA_HOME/bin
    # Ansible Homebrew
    # - MySQL, Maven .....
    export PATH=$PATH:/opt/homebrew/bin
  3. 再执行 ansible 命令的机器配置 /etc/ansible/hosts 设置需操作的主机信息,如:

    [zero]
    ox.engine.cn            # 该地址也已经写入本机host中:127.0.0.1 -> ox.engine.cn

从流程图上可知,前半部分 账号初始化、库初始化 在生产环境和开发环境是一致的,都是使用SSH登录到目标机器执行脚本(Windows会重新开发),后半部分 表初始化、数据初始化 在开发环境使用 liquibase、iac-load.jar 直接执行,而在生产环境则会将初始化内容打包成发布专用的SQL文件,直接执行。

4.2.2. 指令程序

上述流程中有一个后期指令集的功能,但图上只列举了常用的数据导入部分,开发过程中现阶段支持三个指令程序:

iac 的全称:Infrastructure As Code,inst 的全称:单词指令:Instruction 的缩写。

插件指令程序是为当前应用做所有容器启动前的预处理配置专用,一旦数据库准备好之后,您就可以直接运行所有的插件指令程序完成所需的操作。

名称 说明

inst-load.jar

配置数据导入器,负责所有现存配置数据的导入流程。

inst-atom.jar

建模管理器,负责所有动态建模数据的导入(需在环境变量中设置:DB_ATOM=true )。

inst-menu.jar

菜单规划器,负责所有菜单的重命名、排序、父子级连接。

有了 菜单规划器 之后,新版本的程序导入不需要导入菜单中的 ORDER(排序)、PARENT_ID(父子级关系)、TEXT(菜单名称)、LEVEL(菜单等级) 等核心字段,这样Excel配置文件中的菜单数据就彻底被简化了。

所有的 指令程序 都是可以独立运行的,您也可以直接找到对应的 main 函数作为单独的 Java Console 程序去执行,最终产生的效果都是一致的,Zero 中针对大量的程序执行做过 幂等性 处理,所以您也不用担心反复执行带来的副作用问题。

4.2.3. 指令程序调试

若您在部署过程中无法正确执行 指令程序(如:数据导入失败、建模失败、配置格式有问题),那么您可以开启指令程序的调试。

由于拆分之后 Maven 项目的类路径的问题,所以指令程序不可以直接执行,会遇到无法提取资源文件的问题(资源文件在启动器中),所以在调试 指令程序 时必须将启动代码拷贝到 启动器 项目中。

  1. 拷贝指令程序主代码到启动器中,如下截图:

    0

  2. 指令程序主函数代码一般比较简单(注意不要忘记 @Up 的注解),如:

    package cn.vertxup.inst;
    
    import io.mature.boot.routine.EngrossAtom;
    import io.vertx.up.annotations.Up;
    
    @Up
    public class InstAtom {
        public static void main(final String[] args) {
            EngrossAtom.run(InstAtom.class, args);
        }
    }
  3. 然后在 IDEA 中创建启动配置,如下截图:

    0

    3.1. 关于 VM Options

    由于 Zero 开发环境使用了 黑魔法(反射更改内部私有变量值),所以必须在启动参数中追加:

    --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED

    3.2. 关于环境变量

    IDEA 运行的环境变量需要单独设置,参考截图中位置和如下表格:

    变量名 变量值

    Z_NS

    cn.vertxup.{0}

    ZERO_ENV

    Development

    3.3. 关于 ZERO_ENV 变量

    指令程序 的 ZERO_ENV 变量值在调试和真实运行时会有差异,这点需要开发人员注意。

    • 调试程序:ZERO_ENV 的值应设置成 Development。

    • 命令行运行:ZERO_ENV 的值则是默认的 Production。

    虽然对 启动器 而言,使用 IDEA 运行应该是 Development 开发环境的配置,但自动化脚本执行时( run-ansible.sh )这些指令程序的默认环境就应该是 Production,两种环境最大的区别在于配置文件的提取路径,所以这点需要您重点关注。

按照上述步骤在 IDEA 中单独启动指令程序,您就可以直接打断点对启动程序进行调试了。 :data-uri:

4.3. 数据库环境(开发)

本章节主要讲解Zero中数据库初始化流程,默认账号密码如:

类型 账号 说明

MySQL / TiDB

root

root账号

MySQL / TiDB

zero

核心管理员账号

由于做过脱敏的处理,MySQL 需要您在自己运行的机器上配置 免密码 登录的模式来执行Zero Extension的数据库交互脚本,这样的模式下不依赖环境变量,但更安全,不过这种模式仅用于 Zero 的研发过程而不是开发过程。

4.3.1. MySQL 8.0

4.3.1.1. Docker-Compose

进入到zone@docker/database-dc-mysql-8目录中,该目录中包含了MySQL的Docker-Compose基础配置,为了脱敏操作,下载的版本中没有环境变量文件 zero-mysql-8.env,您可以直接将目录中的模板文件拷贝一份:

$ cd zone@docker/database-dc-mysql-8
$ cp tpl.zero-mysql-8.env zero-mysql-8.env

使用工具或IDE编辑您两个账号的初始密码:

MYSQL_ROOT_PASSWORD=
MYSQL_ROOT_HOST=%
MYSQL_USER=zero
MYSQL_PASSWORD=
参数 含义

MYSQL_ROOT_PASSWORD

root账号密码

MYSQL_ROOT_HOST

root账号访问的host设置,最终为 root@host中host部分

MYSQL_USER

新建MySQL账号名

MYSQL_PASSWORD

新建MySQL账号对应密码(初始化执行即为zero账号授权)

然后执行如下命令启动MySQL:

$ ./zero-mysql-8-@up.sh

运行成功后,您可以使用工具连接MySQL(确认zero/root双账号可连接)。

$ mysql -u zero -P 3306 -h ox.engine.cn
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

确认您的 zero 账号执行过 init 下的初始化脚本,该脚本会为 zero 账号执行授权,您可以在MySQL中查看该账号是否授权成功。

4.3.1.2. Terraform

进入到zone@terraform目录中,该目录中包含了MySQL的所有terraform脚本,为了脱敏操作,下载版本中没有设置环境变量文件 initialize.sh,您可以直接将目录中的 tpl.initialize.sh 拷贝一份:

$ cd zone@terraform/kmini/database-mysql-8
$ cp tpl.initialize.sh initialize.sh

使用工具或IDE编辑您两个账号的初始密码,编辑 initialize.sh(属性同上,此处不累赘)。

#!/usr/bin/env bash
export TF_VAR_mysql_password=
export TF_VAR_mysql_root_password=
export TF_VAR_mysql_data_path=${PWD}/data

# 编辑完成后执行
$ source ./initialize.sh

然后在目录中依次执行下边命令:

# 初始化所有资源
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "3.0.1"...
- Installing kreuzwerker/docker v3.0.1...
- Installed kreuzwerker/docker v3.0.1 (self-signed, key ID BD080C4571C6104C)

Partner and community providers are signed by their developers.
If you''d like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

# 查看执行计划
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # docker_container.terraform-mysql-8 will be created
  + resource "docker_container" "terraform-mysql-8" {
      + attach                                      = false
      + bridge                                      = (known after apply)
      + command                                     = (known after apply)
      + container_logs                              = (known after apply)
      + container_read_refresh_timeout_milliseconds = 15000
      + entrypoint                                  = (known after apply)
      + env                                         = [
          + "MYSQL_PASSWORD=xxxxxx123YH",
          + "MYSQL_ROOT_HOST=%",
          + "MYSQL_ROOT_PASSWORD=xxxxxxijn123",
          + "MYSQL_USER=zero",
        ]
      + exit_code                                   = (known after apply)
      + hostname                                    = "ox.engine.cn"
      + id                                          = (known after apply)
      + image                                       = "mysql:8.0.32"
      + init                                        = (known after apply)
      + ipc_mode                                    = (known after apply)
      + log_driver                                  = (known after apply)
      + logs                                        = false
      + must_run                                    = true
      + name                                        = "terraform-mysql-8"
      + network_data                                = (known after apply)
      + read_only                                   = false
      + remove_volumes                              = true
      + restart                                     = "no"
      + rm                                          = false
      + runtime                                     = (known after apply)
      + security_opts                               = (known after apply)
      + shm_size                                    = (known after apply)
      + start                                       = true
      + stdin_open                                  = false
      + stop_signal                                 = (known after apply)
      + stop_timeout                                = (known after apply)
      + tty                                         = false
      + wait                                        = false
      + wait_timeout                                = 60

      + healthcheck {
          + interval     = (known after apply)
          + retries      = (known after apply)
          + start_period = (known after apply)
          + test         = (known after apply)
          + timeout      = (known after apply)
        }

      + labels {
          + label = (known after apply)
          + value = (known after apply)
        }

      + networks_advanced {
          + aliases = []
          + name    = "mysql_network"
        }

      + ports {
          + external = 3306
          + internal = 3306
          + ip       = "0.0.0.0"
          + protocol = "tcp"
        }

      + upload {
          + content    = <<-EOT
                GRANT ALL PRIVILEGES ON *.* TO 'zero'@'%';
                FLUSH PRIVILEGES;
            EOT
          + executable = true
          + file       = "/docker-entrypoint-initdb.d/account.sql"
        }
    }

  # docker_image.mysql will be created
  + resource "docker_image" "mysql" {
      + id           = (known after apply)
      + image_id     = (known after apply)
      + keep_locally = true
      + name         = "mysql:8.0.32"
      + repo_digest  = (known after apply)
    }

  # docker_network.private_network will be created
  + resource "docker_network" "private_network" {
      + driver      = (known after apply)
      + id          = (known after apply)
      + internal    = (known after apply)
      + ipam_driver = "default"
      + name        = "mysql_network"
      + options     = (known after apply)
      + scope       = (known after apply)

      + ipam_config {
          + aux_address = (known after apply)
          + gateway     = (known after apply)
          + ip_range    = (known after apply)
          + subnet      = (known after apply)
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

# 部署
$ terraform apply

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

docker_network.private_network: Creating...
docker_image.mysql: Creating...
docker_image.mysql: Creation complete after 0s [id=sha256:05b458cc32b9686508b97ef40043702c18572840f7b2936b14f06500363868bamysql:8.0.32]
docker_network.private_network: Creation complete after 2s [id=b6285a9e627492f19fcd001830ddd04a6af1e5df4a6c6aeb501ab0965ce6cf45]
docker_container.terraform-mysql-8: Creating...
docker_container.terraform-mysql-8: Creation complete after 1s [id=b651230638dd8bd576b5ac54bd2edca751154ddafcfd12b1201da6be0e1956e6]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

上述命令执行完成后,您就可以使用客户端连接新的MySQL容器了。

先确认您使用Docker Compose运行的MYSQL容器已经停止运行 docker-compose …​ stop,再执行Terraform版本,由于两个版本使用了相同的宿主机3306端口号,若不停止运行可能会导致创建失败,细心的您会发现Terraform模式下的MySQL并未指定数据目录和日志目录,原因是此处只是为了开发环境使用,详细用法参考 valumes,若您想要删除资源可直接使用下边命令:

terraform destroy

本章节是第一次使用terraform,所以在代码部分我保留了三次执行结果,后续章节再使用terraform时我则会直接忽略不再提供执行结果!

最后还有一个点需要注意,就是 providers.tf 中的代码,由于我使用的MacOS平台,所以此处的值要根据您运行Docker的平台有所变化:

provider "docker" {
  host = "unix:///private/var/run/docker.sock"
}

4.3.2. PgSQL

  • 由于MySQL 5.x和8.x差距比较大,所以才在文件目录中带上了版本号,PgSQL则不需使用版本号标识,直接换镜像名称既可。

  • 如果您使用的是MacOS系统,您可以直接安装 Postgres.app 运行PgSQL(绿色软件)。

4.3.2.1. Docker-Compose

进入到zone@docker/database-dc-pgsql目录中,该目录中包含了PgSQL的Docker-Compose基础配置,为了脱敏操作,下载的版本中没有环境变量文件 zero-pgsql.env,您可以直接将目录中的模板文件拷贝一份:

$ cd zone@docker/database-dc-pgsql
$ cp tpl.zero-pgsql.env zero-pgsql.env

使用工具或IDE编辑您账号的初始密码:

POSTGRES_PASSWORD=
POSTGRES_USER=postgres
POSTGRES_DB=postgres
TZ=Asia/Shanghai
参数 含义

POSTGRES_PASSWORD

postgres账号密码

POSTGRES_USER

默认账号名

POSTGRES_DB

默认账号访问的Schema名

TZ

默认使用的时区

然后执行如下命令启动PgSQL:

$ ./zero-pgsql-@up.sh
4.3.2.2. Terraform

进入到zone@terraform目录中,该目录中包含了PgSQL的所有terraform脚本,为了脱敏操作,下载版本中没有设置环境变量文件 initialize.sh,您可以直接将目录中的 tpl.initialize.sh 拷贝一份:

$ cd zone@terraform/kmini/database-pgsql
$ cp tpl.initialize.sh initialize.sh

使用工具或IDE编辑您两个账号的初始密码,编辑 initialize.sh(属性同上,此处不累赘)。

#!/usr/bin/env bash
export TF_VAR_pgsql_password=
export TF_VAR_pgsql_data_path=${PWD}/data

# 编辑完成后执行
$ source ./initialize.sh

然后在目录中依次执行下边命令就可以部署好PgSQL的Docker版本了:

$ terraform init
$ terraform plan
$ terraform apply

注意 main.tf 中关于网络的代码:

resource "docker_network" "private_network" {
  name = "mysql_network"
}

如果只部署一个是没有问题的,但若在同一个Docker中同时运行MySQL和PgSQL,此处需要修改

resource "docker_network" "mysql_network" {
  name = "mysql_network"
}

否则:Docker 容器无法定位网络使用的哪一个导致 terraform apply命令执行失败!

4.3.3. TiDB

4.3.3.1. Docker Compose

TiDB的Docker Compose版本已经在Cloud工具箱中存在,您可以直接进入zone@docker/database-dc-tidb启动TiDB集群,但由于该集群所需资源比较高昂,所以不建议使用DC方式运行TiDB,当然您机器性能很好就另当别论,最好确认 14个容器 全部在Docker中正常启动,再使用才不会有问题。

4.3.3.1.1. TiUP启动

TiDB官方提供了两种快速上手模式(开发环境和生产环境单机运行就不用考虑了,参考 软硬件环境需求 )。直接进入zone@os/database-os-tidb目录中,先更新TiUP Cluster的所有组件:

$ tiup update --self && tiup update cluster

然后直接运行启动脚本:

# tiup playground v6.5.0 --db 2 --pd 3 --kv 3 --tag tidb-zero
$ ./tidb-start.sh
tiup is checking updates for component playground ...
Starting component `playground`: /Users/lang/.tiup/components/playground/v1.11.2/tiup-playground v6.5.0 --db 2 --pd 3 --kv 3 --tiflash 0 --tag tidb-zero
Playground Bootstrapping...
Start pd instance:v6.5.0
Start pd instance:v6.5.0
Start pd instance:v6.5.0
Start tikv instance:v6.5.0
Start tikv instance:v6.5.0
Start tikv instance:v6.5.0
Start tidb instance:v6.5.0
Start tidb instance:v6.5.0
Waiting for tidb instances ready
127.0.0.1:4000 ... Done
127.0.0.1:4001 ... Done
CLUSTER START SUCCESSFULLY, Enjoy it ^-^
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4001 -u root -p (no password)
To connect TiDB: mysql --comments --host 127.0.0.1 --port 4000 -u root -p (no password)
To view the dashboard: http://127.0.0.1:2379/dashboard
PD client endpoints: [127.0.0.1:2379 127.0.0.1:2382 127.0.0.1:2384]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000

看到上边界面后就可以直接连接4000端口进入TiDB了(默认root密码"")。

4.4. 数据导入

配置数据导入是Zero框架中的重头戏,所以单独开章节并且放到项目初始化流程中讲解,只有数据完整导入之后,您的容器启动后才拥有了 配置数据,没有配置数据的容器启动只是一个空壳,无法启用Zero Extension扩展框架中很多便携的功能。开发模式 下数据导入要注意运行的 Working directory 属性,参考 容器启动,否则您将无法导入数据。

4.4.1. 目录规范

通常Zero中的数据导入目录分两种:启动器级别、模块级别。

4.4.1.1. 启动器

启动器的数据一般位于如下目录:

环境 目录地址

Development(开发)

src/main/resources/init/oob/

Mockito(测试)

src/test/resources/init/oob/

Production(生产)

init/oob(即运行程序当前目录下,若是标准编译则位于 conf/init/oob 目录)

数据文件全部位于上述目录中,根据自身环境而定,所有数据文件格式都是 Excel 格式,模板可参考Zero教程: 二向箔: Excel,程序执行过程中会直接使用 init/oob 作为参数,系统自动计算根目录。

最终,只要是合法的Excel模板文件,都会被直接导入到系统数据表中。

4.4.1.2. 模块级

如果使用了Zero中的模块化架构,则模块内部的文件结构通常如下:

0

每个模块都有自己独立的目录名称,通常是 zero-xx 后边的 xx,为了遵循扩展规范,后续您创建的新模块目录名尽可能不与这些名称冲突,冲突后可能导致配置文件失效。

  1. 每个模块都会包含一个 plugin/xxx/oob 路径,该路径下的数据文件会被导入到环境中。

  2. 二向箔: Excel 教程中的模块级Excel配置全部位于 initialize.yml 文件中,文件内容如:

    - dao: cn.vertxup.ambient.domain.tables.daos.XSourceDao   # X_SOURCE
      key: key
      unique:
        - appId
    - dao: cn.vertxup.ambient.domain.tables.daos.XAppDao      # X_APP
      key: key
      unique:
        - name
    # .....
  3. 只有在 initialize.json 文件中注册过的数据文件可被导入到环境中,否则系统依然会忽略相关数据文件,内容如:

    [
        "plugin/ambient/oob/cab/ambient.app.xlsx",
        "plugin/ambient/oob/cab/system.document.xlsx",
        "plugin/ambient/oob/cab/system.sync_log.xlsx",
        "plugin/ambient/oob/cab/x.activity.xlsx",
        "....",
    ]

AI工具中的 aj mod 可以根据 oob 目录路径自动写入数据到 initialize.json 中执行注册。

虽然模块中包含了数据目录、链接文件等相关信息,您依旧可以在启动器的同名路径下追加目录和文件,追加的目录和文件会直接覆盖模块级(模块优先级会被启动目录下的内容覆盖),最终形成的拓扑结构如下:

0

  1. 启动器中若不定义任何配置文件,则直接使用模块级配置。

  2. 启动器中的Excel导入导出一旦打开,则会自动链接模块级 initialize.yml 配置文件(保证每张表的配置只在全局环境中出现一次)。

  3. aj mod 命令可以帮助模块做模块级配置,根据数据文件写 initialize.json 配置,参考如:

    aj mod -p src/main/resources/plugin/xxx/oob

模块数据导入配置已经从 Extension 转移到了根路径中的 vertx.yml 配置,0.9.0 版本之后直接使用新配置(本文只讲解新配置,注意类名变化):

# 「模块配置导入」-----------------------------------------------------------------------
boot:
  component:
    on: io.vertx.up.lightway.OnBoot
  config:
    on: io.vertx.up.lightway.OnBootConfig
  extension:
    - executor: io.vertx.mod.ambient.booter.AmbientOOB
    - executor: io.vertx.mod.rbac.booter.RbacOOB
    - executor: io.vertx.mod.erp.booter.ErpOOB
    - executor: io.vertx.mod.psi.booter.PsiOOB
    - executor: io.vertx.mod.fm.booter.FmOOB
    - executor: io.vertx.mod.ui.booter.UiOOB
    - executor: io.vertx.mod.jet.booter.JetOOB
    - executor: io.vertx.mod.graphic.booter.GraphicOOB
    - executor: io.vertx.mod.atom.booter.AtomOOB
    - executor: io.vertx.mod.lbs.booter.LbsOOB
    - executor: io.vertx.mod.workflow.booter.WfOOB
    - executor: io.vertx.mod.is.booter.IsOOB
    - executor: io.vertx.mod.battery.booter.BatteryOOB
    - executor: io.vertx.mod.tpl.booter.TplOOB    # 新版Tpl

上述Java类的定义代码如下:

package io.vertx.mod.ambient.booter;

import io.vertx.mod.ke.cv.KeIpc;
import io.vertx.up.plugin.booting.AbstractBoot;

public class AmbientOOB extends AbstractBoot {
    public AmbientOOB() {
        super(KeIpc.Module.AMBIENT);
    }
}

若您不想启用Zero Extension模块的内容,就不用在 vertx.yml 中配置扩展模块导入器( extension 节点),如此您在执行导入程序时就会跳过OOB数据配置。您若想导入自己的数据,有两种做法:

  1. 按照白皮书中的模块化架构,使用本章导入数据规范开发新的 AbstractBoot 组件,执行本章的模块化配置。

  2. 若您的功能不想做成模块化,直接将数据文件放到启动器的 init/oob 目录中,并按照Zero标准教程中配置对应的Excel导入/导出功能。

4.4.2. 规则:Excel单元格

若您在Excel单元格中填写如下:

JSON:authority/auth.menu/ui.surface.json

该单元格会被导入成JSON格式:

0

上述规则会让单元格关联JSON文件做导入:

0

此规则的优点有两个:

  1. 单元格内如果出现了配置重复,可让该单元格引用同一个配置文件,一改既改,这样配置数据很容易维护。

  2. JSON格式不用直接填写在Excel中,而是用外联文件,可压缩Excel的体积,让Excel可读性增强。

4.4.3. 规则:默认值/限制/转换

Zero为导入程序提供了一个环境数据文件,文件地址位于启动器下的如下位置:

init/environment.json

该文件的规则如下:

{
    "global": {
        "sigma": "Qxw5HDkluJF...",
        "appId": "6c2a902b-db2c-...",
        "appKey": "wRSQWM8GtOugMe4V...",
        "language": "cn",
        "active": true,
        "createdBy": "zero-environment",
        "scope": "vie.app.xc",
        "namespace": "cn.originx.vie.app.xc"
    },
    "application": {
        "name": "vie.app.xc"
    },
    "dictionary": {
        "S_PERM_SET": {
            "type": {
                "系统数据管理": "bacdb62f-0f74-...",
                "业务数据管理": "faabb94c-1151-...",
                "开发实施管理": "50615da8-1a89-...",
                "安全管理": "670565fd-40ea-..."
            }
        },
        "B_BAG": {
            "name": {
                "客户管理": "供应商管理"
            },
            "nameAbbr": {
                "CM": "VM"
            },
            "nameFull": {
                "Customer Management": "Vendor Management"
            }
        }
    },
    "forbidden": {
        "X_MENU": {
            "name": [
                "zero.customer",
                "zero.customer.corporation",
                "zero.customer.account",
                "zero.data.psi.commodity",
                "zero.ssm.data"
            ]
        }
    }
}

上述四种规则说明如下:

节点 说明

global

该节点为一个JsonObject,之中的数据会被复用到每一张数据表,只要存在global中定义的字段,该字段都会被设置成文件中定义的值,多租户、多应用、多语言平台可以直接复用数据模板,为不同应用导入相同的OOB配置。

application

(测试专用)启用测试框架时,该节点可以帮助开发人员模拟应用环境,并定制应用所需的上下文信息。

dictionary

字典全局替换,字典全局替换层级一般为 <TABLE>/<ATTRIBUTE>/,它表示将某个表某个字段中的值替换成自定义的值,可做用户级的配置重定义。如上述示例中:S_PERM_SET 表中的 type 字段一旦出现了 系统数据管理 的文本会被替换成对应的UUID格式。

forbidden

数据过滤器,该节点定义的数据不会被导入到系统中,数据最好是唯一条件,如上述示例中 name 包含的这些类型菜单都不会被导入到系统中,通常是为了屏蔽OOB数据特殊导入而量身定制。

新版已经包含了 路由规划表,所以菜单级别的过滤可以不用在 forbidden 中执行,但其他内容依旧可以在此过滤;路由规划表每个应用的不一样,除了可以过滤路由信息之外,还可以调整路由的具体树型结构,以实现路由的完整规划,系统自动帮助完成调整,结合导入部分的幂等性,可反复执行脚本来完成路由的编排。

4.5. 扩展:办公协同

Zero Ui中的办公协同,主要针对Office的套件( Word, Excel, PPT,PDF )进行在线的协同浏览/编辑,集成了开源版的 ONLYOFFICE 套件,此套件依赖后端运行一个特殊的文档服务器,所以本文提供开发和生产场景下的服务器搭建流程,让开发人员可以完善扩展模块 zero-is / zero-doc 的文档管理以及文档阅览功能。

4.5.1. ONLYOFFICE

4.5.1.1. 安装教程

根据您自身操作系统需求选择对应的安装教程:

zero doc server install

4.5.1.2. 基本介绍

在搭建文档服务器之前先看看 ONLYOFFICE 产品线( Community / Enterprise / Developer 三种版本):

产品名 含义

Docs

提供平台使用的文档编辑器,可以和内置的文档服务器集成(本章内容)。

DocSpace

提供文档协同专用的在线办公室,侧重于工具。

Workspace

工作空间,您可以在这个空间中做项目管理,直接和项目管理强相关的工作区间。

Connectors

和其他平台集成用的连接器。

Apps

各种不同平台对应的终端。

ONLYOFFICE 产品线上会包含 Document Server 以及 Community Server 两个服务端,这两个服务端的区别在于:

  • Document Server:直接和内置 Docs 工具集成专用提供编辑器的服务器,编辑器包括:

    • Document Editor:编辑 Word 文档专用。

    • Spreadsheet Editor:编辑 Excel 文档专用。

    • Presentation Editor:编辑 PPT 文档专用。

    • Form Creator:表单编辑器。

    • PDF reader / converter:PDF阅读器和转换器。

  • Community Server:集成专用服务器,提供了 REST 的 API 接口。

其他额外的内容参考:ONLYOFFICE文档中心。

教程中主要使用第一个开源产品 ONLYOFFICE Docs,它是一个开源办公套件,包含了文本文档(Word)、电子表格(Excel)、演示文稿(PPT)的编辑器,功能点如下:

  • 创建、编辑、查看对应的文本文档(Word)、电子表格(Excel)、演示文稿(PPT)。

  • 和其他团队成员协同处理文档。

  • 查看PDF、导入/导出PDF。

  • 将文档转换成 Markdown / HTML 等相关格式。

  • 将课本转化成电子书。

从 6.4 版本开始,Docs 提供了对 Web 应用程序开放平台接口协议( WOPI )的支持(一种 REST 协议),用于将您的应用程序和在线办公室集成,它允许您打开存储在服务器上的文件、编辑、保存它们。

它支持的所有格式包括:DOC, DOCX, ODT, RTF, TXT, PDF, HTML, EPUB, XPS, DjVu, XLS, XLSX, ODS, CSV, PPT, PPTX, ODP。

4.5.2. Docker安装

Docker默认指定了 Google DNS 服务器,若您无法从互联网访问,则您需要修改Docker的DNS设置保证您可以访问镜像服务器,如常见的Linux的配置位于 /etc/default/docker 文件中,有几种方法可以解决这个问题:

命令方式

在启动命令中使用 docker_OPTS="--dns 8.8.8.8" 参数。

基于 RPM 的系统:

  1. 创建配置文件 /etc/docker/daemon.json 文件,配置内容如下:

    {
        "dns": [ "8.8.8.8" ]
    }
  2. 重启Docker服务

    sudo systemctl restart docker.service
4.5.2.1. 基本命令

若安装了Docker,那么您可以使用如下命令启动:

# 有必要追加 sudo
# 直接启动
docker run -i -t -d -p 5600:80 --restart=always -e JWT_SECRET=my_jwt_secret onlyoffice/documentserver:latest

# 您可以先试用如下命令单拉镜像(省掉运行时的镜像拉取时间)
docker pull onlyoffice/documentserver:latest

从 7.2 的版本开始,若您没有指定 JWT_SECRET 参数,系统会随机生成,且切换虚拟机(VM)和物理机启动时会重新生成,这会给集成带来一定的问题,所以此处最好您直接使用自定义的值:

  • 使用JWT:-e JWT_SECRET=xxxx。

  • 关闭JWT:-e JWT_ENABLED=false。

4.5.2.2. 存储分离

ONLYOFFICE 中的所有数据都是存储在指定目录中的:

目录 含义

/var/log/onlyoffice

存储 ONLYOFFICE Docs 的日志数据

/var/www/onlyoffice/Data

存储证书信息

/var/lib/onlyoffice

文件缓存

/var/lib/postgresql

数据库文件

若您想要将这些数据存储到容器之外,您可以使用 -v 选项,最终执行命令如下(端口号使用 31017 ):

# 生成自己的 my_jwt_secret,直接使用 ai str -n 1 -l 36
ai str -n 1 -l 36
# 假设:OaBgxq6UYs6IWBSHdUlMswUDmghZIH2cLmK1

docker run -i -t -d -p 31017:80 --restart=always \
    -v $PWD/app@runtime/doc-office/logs:/var/log/onlyoffice \
    -v $PWD/app@runtime/doc-office/data:/var/www/onlyoffice/Data \
    -v $PWD/app@runtime/doc-office/lib:/var/lib/onlyoffice \
    -v $PWD/app@runtime/doc-office/db:/var/lib/postgresql \
    -e JWT_SECRET=OaBgxq6UYs6IWBSHdUlMswUDmghZIH2cLmK1 onlyoffice/documentserver:latest

若将 Docker 使用在生产环境,强烈建议将数据文件存储到容器之外,这种做法和使用 Docker 运行数据库是一个原理。而在Zero脚手架中,新的文档服务器的规划目录放到启动器的 app@runtime/doc-office 目录下,此处的目录基础规划如:

目录/文件 含义

<app>/app@runtime/doc-office

应用根目录,当前目录使用 ${PWD} 环境变量可以得到绝对路径。

<app>/app@runtime/doc-office/logs

对应 /var/log/onlyoffice 日志数据。

<app>/app@runtime/doc-office/data

对应 /var/www/onlyoffice/Data 数据目录。

<app>/app@runtime/doc-office/lib

对应 /var/lib/onlyoffice 文件缓存。

<app>/app@runtime/doc-office/db

对应 /var/lib/postgresql 数据库文件。

4.5.3. Docker-Compose

开发推荐:这种方式可以自己修改配置文件,然后使用 docker-compose 拉起 ONLYOFFICE 的服务,先下载库:

git clone https://github.com/ONLYOFFICE/Docker-DocumentServer

修改项目中的 docker-compose.yml 配置文件(只更改端口号部分)

version: '2'
services:
  onlyoffice-documentserver:
    build:
      context: .
    container_name: onlyoffice-documentserver
    depends_on:
      - onlyoffice-postgresql
      - onlyoffice-rabbitmq
    environment:
      - DB_TYPE=postgres
      - DB_HOST=onlyoffice-postgresql
      - DB_PORT=5432
      - DB_NAME=onlyoffice
      - DB_USER=onlyoffice
      - AMQP_URI=amqp://guest:guest@onlyoffice-rabbitmq
      # Uncomment strings below to enable the JSON Web Token validation.
      #- JWT_ENABLED=true
      #- JWT_SECRET=secret
      #- JWT_HEADER=Authorization
      #- JWT_IN_BODY=true
    ports:
      - '20080:80'                      # 端口映射 20080 -> 80
      - '20443:443'                     # 端口映射 20443 -> 443
    stdin_open: true
    restart: always
    stop_grace_period: 60s
    volumes:
      - /var/www/onlyoffice/Data
      - /var/log/onlyoffice
      - /var/lib/onlyoffice/documentserver/App_Data/cache/files
      - /var/www/onlyoffice/documentserver-example/public/files
      - /usr/share/fonts

  onlyoffice-rabbitmq:
    container_name: onlyoffice-rabbitmq
    image: rabbitmq
    restart: always
    expose:
      - '5672'

  onlyoffice-postgresql:
    container_name: onlyoffice-postgresql
    image: postgres:9.5
    environment:
      - POSTGRES_DB=onlyoffice
      - POSTGRES_USER=onlyoffice
      - POSTGRES_HOST_AUTH_METHOD=trust
    restart: always
    expose:
      - '5432'
    volumes:
      - postgresql_data:/var/lib/postgresql

volumes:
  postgresql_data:

依次执行如下命令:

# 进入目录中,docker-compose.yml 已改过
cd Docker-DocumentServer

# 然后拉起
docker-compose up -d

# 停止使用如下命令
docker-compose down

第一次由于镜像、依赖库下载等各种问题,速度会慢一点(保证您的网络连通性),执行过程中您可以看到如下截图:

zero doc docker compose

4.5.4. Ubuntu

本章提供在 Ubuntu ( Ubuntu Server 22.04.3 LTS )上安装的详细流程,此部分内容同时支持开发环境/生产环境。

项 需求

CPU

> 2GHz

RAM(内存)

> 2GB

HDD(硬盘)

> 40GB

SWAP

> 4GB

OS

内核版本超过 3.13(执行 uname -a 查看)

其他库

  • PostgreSQL > 12.9

  • NGINX > 1.3.13

  • libstdc++6 > 4.8.4

  • RabbitMQ

前文中已经配置过 ox.office.cn 域名映射的IP地址,所以本章节所有的配置都配置到此域名下,推荐搭建环境时使用域名替换掉IP,不论是局域网DNS还是伪集群模式,使用域名是最好的方式,以防止IP地址变化导致配置的大规模更新;不仅如此,在搭建 Document Server 的机器上还需要设置如下Host:

域名 含义

ox.server.cn

Zero Ui的运行服务器。

ox.engine.cn

Zero 后端的运行服务器。

ox.office.cn

Document Server文档服务器。

由于实例运行在局域网中,安装配置之前先按如下步骤检查防火墙并关闭:

# 查看防火墙状态
# inactive - 禁用
# active - 启用
sudo ufw status
# 禁用防火墙
sudo ufw disable
4.5.4.1. 依赖库

下边是安装 ONLYOFFICE 所需的依赖库:

库 备注

libcurl3

一个用于处理网络数据传输的开源库,它提供了一个简单的 API,允许开发人员通过多种协议(如HTTP、FTP、SCP、SFTP等)发送和接收数据。

libxml2

libxml2 是一个用于解析和处理XML(可扩展标记语言)文档的开源库,libxml2 提供了一套功能强大的工具,用于读取、解析、创建和修改XML文档,使开发人员能够在各种应用程序中处理XML数据。

fonts-dejavu

fonts-dejavu 是一个开源字体包,包含了 DejaVu 字体系列的字体文件,这些字体是基于 Bitstream Vera 字体系列的扩展,旨在提供广泛的字符集支持,包括拉丁字母、希腊字母、西里尔字母以及各种特殊字符和符号。

fonts-liberation

fonts-liberation 是一个字体包,旨在提供一组兼容微软字体的开源替代品,这些字体与微软的字体(例如Times New Roman、Arial和Courier New)在外观和排版上非常相似,但它们是自由和开源的,可以在各种操作系统上自由使用、分发和修改。

ttf-mscorefonts-installer

ttf-mscorefonts-installer 是一个用于在Linux系统上安装微软核心字体(Microsoft Core Fonts)的软件包,微软核心字体是一组由微软创建并在其操作系统中广泛使用的字体,包括常见的字体如Arial、Times New Roman、Courier New等。

fonts-crosextra-carlito

fonts-crosextra-carlito 是一种字体包,提供了 Carlito 字体,这是对微软 Calibri 字体的开源替代品,Calibri 是一种常见的无衬线字体,通常用于文档和电子邮件等办公应用程序中。

fonts-takao-gothic

fonts-takao-gothic 是一个字体包,包含了 Takao 字体家族的高丽字体(Gothic)变种。Takao 字体是一组用于支持多种亚洲语言字符集的开源字体。

fonts-opensymbol

fonts-opensymbol 是一个字体包,包含了开源的 OpenSymbol 字体。OpenSymbol 字体是一种特殊的字体,用于显示各种符号、图标和特殊字符,通常与办公套件和文档处理软件一起使用。

执行如下命令安装上述库:

# 1. libcurl3 已经没有提供安装源了,所以此处使用 libcurl4 替换
# 2. 此处执行时需使用 sudo 提升权限
sudo apt install libcurl4 libxml2 fonts-dejavu fonts-liberation ttf-mscorefonts-installer fonts-crosextra-carlito fonts-takao-gothic fonts-opensymbol

按照官方教程提及,若安装的是 14.04 TLS 或旧版本才需安装上述依赖库,但由于部分内容已经存在更新包,所以依旧执行一次上述命令,当您看到如下信息证明依赖库已全部安装完成:

zero doc dep

4.5.4.2. PostgreSQL

ONLYOFFICE 依赖 PgSQL 数据库,本章节提供 PgSQL 在 Ubuntu 上的安装。

  1. 执行下边命令先安装 PgSQL 数据库:

    sudo apt-get install postgresql
  2. 安装完成后,您需要为 ONLYOFFICE 初始化数据库:

    sudo -i -u postgres psql -c "CREATE USER onlyoffice WITH PASSWORD 'onlyoffice';"
    sudo -i -u postgres psql -c "CREATE DATABASE onlyoffice OWNER onlyoffice;"
  3. (局域网访问)编辑 PgSQL 的配置文件:

    1) postgresql.conf 编辑

    sudo vim /etc/postgresql/14/main/postgresql.conf

    找到配置文件中的如下配置,并更改:

    listen_addresses = '*'

    2) pg_hba.conf 编辑

    sudo vim /etc/postgresql/14/main/pg_hba.conf

    在配置文件末尾追加如下:

    # Local Network connect on [ADDRESS] section
    host    all             all             0.0.0.0/0               scram-sha-256

    3)重启服务

    更改配置文件之后,执行如下命令:

    sudo systemctl restart postgresql
  4. 打开数据库连接工具,并使用 onlyoffice/onlyoffice 账号密码访问(确认可连接即可):

    zero doc pg

4.5.4.3. RabbitMQ

RabbitMQ 是一个开源的消息队列中间件(Message Broker),它实现了高级消息队列协议(AMQP)的标准,消息队列是一种用于在不同的应用程序或组件之间传递消息的通信方式,它们通常用于解耦不同部分的应用程序,以便它们可以独立运行和扩展。

您可以按照如下步骤搭建 Ubuntu 上的 MQ:

  1. 由于 RabbitMQ 依赖 Erlang 语言环境的支持,所以先要安装 Erlang 环境:

    # 依赖库
    sudo apt install build-essential
    sudo apt install libncurses5-dev
    sudo apt install libssl-dev
    sudo apt install unixodbc unixodbc-dev
    sudo apt install freeglut3-dev libwxgtk2.8-dev          # Couldn't find any package by glob 'libwxgtk2.8-dev'
    sudo apt install xsltproc
    sudo apt install fop
    sudo apt install tk8.6
    
    # 语言环境(安装完成后执行 `erl`)
    sudo apt install erlang

    这些库的作用如下:

    库 备注

    build-essential

    一个用于在Linux操作系统上设置开发环境的包集合,它通常用于Debian和Ubuntu等基于Debian的Linux发行版,包括编译器(GCC)、构建工具(Make)、基本开发库(libc)。

    libncurses5-dev

    用于开发基于文本界面的终端应用程序的开发库,它是ncurses库的开发包,通常用于在Linux和类Unix操作系统上创建具有文本用户界面(TUI)的应用程序。

    libssl-dev

    是用于开发与安全套接字层(SSL)和传输层安全性(TLS)相关的应用程序的开发包,这个包通常在Linux和类Unix操作系统上提供,用于支持安全的网络通信。

    m4

    一个用于文本处理的实用工具,通常用于自动化文本文件的生成和转换。

    unixodbc unixodbc-dev

    是与数据库连接相关的库和开发工具,通常在Unix和Unix-like操作系统上使用,它们用于支持在这些操作系统上连接和访问各种数据库管理系统(DBMS)的应用程序。

    freeglut3-dev libwxgtk2.8-dev

    两个不同的开发包,用于开发图形用户界面(GUI)应用程序,通常在Linux和类Unix操作系统上使用。

    xsltproc

    一个命令行工具,用于处理XML文档并执行XSLT(Extensible Stylesheet Language Transformations)转换。

    fop

    一个开源的Java应用程序,用于将XSL-FO(Extensible Stylesheet Language - Formatting Objects)文档转换为PDF和其他输出格式,XSL-FO是一种XML格式,用于描述文档的外观和格式化要求,包括字体、排版、页眉、页脚、段落和表格等。

    tk8.6

    Tcl/Tk图形用户界面(GUI)工具包的一个特定版本,Tcl(Tool Command Language)是一种脚本编程语言,而Tk是一个用于创建图形用户界面的工具包。

  2. RabbitMQ 的安装和状态查看:

    # 安装
    sudo apt install rabbitmq-server
    # 状态查看
    sudo systemctl status rabbitmq-server
    # < 18.04+, 执行如下
    sudo apt install nginx-extras
  3. RabbitMQ 的日志信息查看:

    直接进入日志目录查看日志信息:

    cd /var/log/rabbitmq/

    zero doc rmqlog

    将带有 rabbit@ 前缀的日志打开(后边跟 host 名),您可以看到当前服务是否查找到对应配置目录:

    zero doc rmqss

  4. RabbitMQ 配置局域网访问(由于关闭了防火墙,所以不需要相关设置,生产环境不推荐):

    cd /etc/rabbitmq/
    vim rabbitmq.config
    # 内容:[{rabbit, [{loopback_users, []}]}].
    # 注意上述配置中最后一个英文句点 . 不可以丢,若丢了会导致启动失败
    
    # 修改完成后重启
    sudo systemctl restart rabbitmq-server

    此处配置的 [{rabbit, [{loopback_users, []}]}]. 意思是开放使用,rabbitmq 默认创建用户 guest,密码也是 guest,值允许 localhost 访问,若要外部访问则必须加上上述配置。

  5. 安装管理平台,安装之后重启:

    sudo rabbitmq-plugins list                          # 查看目前有的插件列表
    sudo rabbitmq-plugins enable rabbitmq_management    # 启用管理平台

    zero doc rmanage

  6. 重启完成之后浏览器打开:http://ox.office.cn:15672/(此处的 ox.office.cn 已经在前边章节配置了),账号密码使用 guest/guest:

    zero doc mqgui

4.5.4.4. ONLYOFFICE Docs

安装 Docs 之前,您需要先看看此产品的端口相关内容,参考如下表格(完整版参考:Ports List):

端口号 服务

80

HTTP

443

HTTPS

4369

Erlang

5432

PostgreSQL

5672

RabbitMQ

6379

Redis

8000

DocService

8080

Spellchecker

若您想要更改 debconf 系统的默认端口,则您可以执行如下命令:

# Zero Framework 中推荐端口号 5600
echo onlyoffice-documentserver onlyoffice/ds-port select <PORT_NUMBER> | sudo debconf-set-selections

如果您想将 ONLYOFFICE Docs 协议更改为 HTTPS,请不要将端口更改为 443,而是参考官方的专用说明:Switching to HTTPS Protocol。

参考如下步骤安装 Docs:

  1. 添加 GPG Key:

    mkdir -p -m 700 ~/.gnupg
    
    curl -fsSL https://download.onlyoffice.com/GPG-KEY-ONLYOFFICE | gpg --no-default-keyring --keyring gnupg-ring:/tmp/onlyoffice.gpg --import
    
    chmod 644 /tmp/onlyoffice.gpg
    
    sudo chown root:root /tmp/onlyoffice.gpg
    
    sudo mv /tmp/onlyoffice.gpg /usr/share/keyrings/onlyoffice.gpg
  2. 追加 ONLYOFFICE Docs 的库:

    echo "deb [signed-by=/usr/share/keyrings/onlyoffice.gpg] https://download.onlyoffice.com/repo/debian squeeze main" | sudo tee /etc/apt/sources.list.d/onlyoffice.list
  3. 更新包缓存:

    sudo apt update

    zero doc deb

  4. 执行如下命令安装

    # Fonts(依赖项部分已安装)
    sudo apt install ttf-mscorefonts-installer
    
    # OnlyOffice(安装过程要提供 PgSQL中的密码)
    sudo apt install onlyoffice-documentserver

其他 Linux 版本如 CentOS 的安装流程,开发人员可参考官方文档和本章提到的步骤自行研究。

4.5.4.5. JWT

ONLYOFFICE 从 7.2 开始默认会开启 JWT,若您没有为它配置任何密钥 secret,那么它会随机生成一个密钥,若是使用 Docker 模式启动,您可以使用如下两个选项进行配置:

选项 含义

JWT_ENABLED

是否开启 JWT,默认是 true,若想要关闭可以选择 false。

JWT_SECRET

设置 JWT 的值,若此处不设置,则 ONLYOFFICE 会为它随机生成。

安装完成之后,secret 会存储在配置文件 /etc/onlyoffice/documentserver/local.json 中,您可以检查属性 services.CoAuthoring.secret.browser.string。其中 /etc/onlyoffice/documentserver/ 是 ONLYOFFICE 的配置目录,此目录中还有一个 default.json 的配置文件,根据官方的教程推荐,配置处理仅编辑 local.json 即可,不要直接编辑 default.json 文件的内容——每次重新启动 Docker 容器或升级 文档服务器 到新版本时都会恢复默认值,并且所有的更改都将丢失。参考如下示例(只和 JWT 相关的部分):

{
    "services": {
        "CoAuthoring": {
            "secret": {
                "inbox": {
                    "string": "secret"
                },
                "outbox": {
                    "string": "secret"
                },
            },
            "token": {
                "enable": {
                    "browser": true,
                    "request": {
                        "inbox": true,
                        "outbox": true
                    }
                }
            }
        }
    }
}

配置 JWT 时需理解如下参数:

参数 含义

services.CoAuthoring.secret.browser.string

「Deprecated」定义了在客户端浏览器请求ONLYOFFICE Docs生成令牌的秘钥。自版本 7.2 起请改用 services.CoAuthoring.secret.inbox.string。

services.CoAuthoring.secret.inbox.string

自版本 7.2 起,该项定义了在来自文档存储服务到文档命令服务、文档转换服务和文档构建服务的传入HTTP请求中生成令牌的秘钥,以及在客户端浏览器请求ONLYOFFICE Docs时生成令牌的秘钥。

services.CoAuthoring.secret.outbox.string

定义了用于在文档编辑服务发送的传出HTTP请求中生成令牌的秘钥,以供回调URL地址使用。

services.CoAuthoring.token.enable.browser

定义客户端浏览器请求中的令牌是否启用。

services.CoAuthoring.token.enable.request.inbox

定义传入的HTTP请求中的令牌是否启用。

services.CoAuthoring.token.enable.request.outbox

定义传出的HTTP请求中的令牌是否启用。

4.5.5. 验证结果

4.5.5.1. 基本环境
  1. 修复配置,若您的配置有问题,可使用如下命令修复:

    zero doc e dpkg

    sudo dpkg --configure -a
    # 下边是输出
    Setting up onlyoffice-documentserver (7.4.1-36) ...
    Generating AllFonts.js, please wait...Done
    Generating presentation themes, please wait...Done
    Generating js caches, please wait...Done
    Installing plugins, please wait...
    # 最后一个步骤十分慢,需要等待很久才可以
  2. 浏览器打开:http://ox.office.cn:5600 地址,您可以看到如下界面,就基本证明:

    zero doc ui

如此您就可以在前端使用 Document Server 了,高级配置可参考官方教程。

4.5.5.2. 诊断/调试

由于修改了配置之后您需要将整个服务重启才可以生效,本章节提供 ONLYOFFICE 的基本命令辅助诊断/调试。

  1. 直接进入 /var/log/onlyoffice/documentserver 目录,此目录结构如下:

    文件 含义

    converter/out.log

    Docs Converter 输出日志

    converter/err.log

    Docs Converter 错误日志

    docservice/out.log

    Docs Docservice 输出日志

    docservice/err.log

    Docs Docservice 错误日志

    metrics/out.log

    Docs Metrics 输出日志

    metrics/err.log

    Docs Metrics 错误日志

    nginx.error.log

    Nginx 错误日志

  2. 您可以使用如下命令查看后台服务的状态,默认情况只会安装 Converter / Docservice / Metrics 三个服务:

    # 所有 ONLYOFFICE 安装完成之后的服务都带有 ds- 前缀
    systemctl status ds-*