sysom1/docs/develop_guide.md

305 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SysOM 开发指南
## 1. 目录介绍
### 1.1 源码目录介绍
```bash
.
├── conf => 全局配置文件
├── deps => 第三方依赖组件Nginx,Redis,Mysql..
├── docker => Dockerfile配置
├── docs => 项目文档
├── environment => 开发环境
├── LICENSE
├── package_rpm_offline.sh => 构建离线 RPM 包脚本
├── package_rpm_online.sh => 构建在线 RPM 包脚本
├── package.sh => 构建 tar.gz 发行包脚本
├── README.md
├── script => 后端微服务部署脚本
├── sysom_server => 微服务目录
├── sysom_web => 前端目录
└── template => 微服务模板
```
- `conf` :全局配置文件目录,`conf/config.yml` 是所有微服务公共的配置文件具体配置相关描述见2.2
- `deps`:第三方依赖组件目录,包含 SysOM 平台依赖的第三方组件,目前主要包括以下组件:
- Mysql
- Redis
- Nginx
- Prometheus
- Grafana
- `docker`Dockerfile 配置目录,用于生成 SysOM 容器;
- `docs`:项目文档目录,包含用户使用手册和开发文档;
- `enviroment`:开发环境目录,定义了微服务开发所需要的公共环境,目前包括以下两个部分:
- env => 微服务公共虚拟环境
- sdk => SysOM 平台自研 SDK 目录
- `LICENSE`:项目 license
- `package_rpm_offline.sh`离线RPM包构建脚本执行本脚本可以一键构建离线 RPM 包,支持在无法连网的离线环境使用;
- `package_rpm_online.sh`在线RPM包构建脚本执行脚本可以一键构建在线RPM包在线RPM包体积较小在联网环境下才可使用安装部署时会自动下载安装所需依赖
- `package.sh`tar.gz 格式发行包构建脚本,执行脚本可以一键构建发行包,内置部署脚本解压后可一键部署(在联网环境下才可使用,安装部署时会自动下载安装所需依赖);
- `README.md`:项目介绍
- `script`:后端微服务部署脚本,`script/server`目录下每个子目录对应一个同名的微服务,每个子目录中包含以下几个脚本:
- `deploy.sh` :微服务的部署脚本,部署阶段脚本执行基础的部署操作(文件的复制移动、依赖安装等),不能执行依赖运行时环境(比如数据库)的操作;
- `init.sh`:微服务的初始化脚本,初始化阶段脚本在部署完成后,第一次运行程序之前执行,可以做一些需要和运行时环境交互的初始化操作(比如微服务的数据库迁移操作依赖数据库);
- `clear.sh`:微服务的清理脚本,用于微服务卸载时清理相关的资源(对于公共服务,比如依赖数据库,不能再清理脚本中卸载数据库,会破坏其它微服务的依赖,只清理本微服务自己生成的资源即可);
- `db_migrate.sh`:微服务的数据库迁移脚本,如果微服务使用了数据库,应当在该脚本下定义如何执行数据库迁移
- `start.sh`:微服务的启动脚本
- `stop.sh`:微服务的停止脚本
- `sysom_server`:微服务目录,每个子目录对应一个微服务
- `sysom_web`SysOM前端项目
- `template`:微服务模板目录,用于一键创建微服务,具体新增微服务方式见 [2-sysomframework-统一框架](#2-sysomframework-%E7%BB%9F%E4%B8%80%E6%A1%86%E6%9E%B6)
### 1.2 部署目录介绍
## 2. SysomFramework 统一框架
### 2.1 SysOM 配置说明
由于 SysomFramework 内部会读取配置文件进行一系列的解析封装因此在介绍SysomFramework之前先对微服务读取配置的流程以及具体包含哪些配置项进行说明。
![](https://intranetproxy.alipay.com/skylark/lark/0/2023/jpeg/67256280/1684756632088-825f77b0-d30c-488d-8e34-3edce1516bea.jpeg)
如上图所示的是一个微服务加载配置的过程:
1. 首先一个微服务的配置有两个来源:
1. 全局配置global config定义在 `conf/config.yml`(在实际部署时会被放置在 `/etc/sysom/config.yml`),定义了所有微服务共享的配置;
2. 微服务配置service config定义在每个微服务根目录下名为 `config.yml`
2. **两个配置文件的可配配置项是完全一致的**,读取时使用 ConfigParser 读取两个文件,内部会自动合并两个配置,**微服务配置中的同名配置项会覆盖全局配置中对应的配置项**,最终得到一个合并后的配置供微服务使用。
目前一级配置项的划分如下:
- `sysom_global`:定义整个项目的全局配置
- `sysom_server`:定义所有微服务共享的配置(比如数据库配置)
- `sysom_service`:定义每个微服务自己的配置
- `sysom_web`:定义 SysOM 前端相关配置
- `sysom_node`:定义 SysOM 节点相关配置
#### 2.1.1 sysom_global 配置
| **配置项** | **说明** | **默认值** |
| -------------- | ------------ | ---------------- |
| path.root_path | 项目部署目录 | /usr/local/sysom |
| timezone | 时区 | "Asia/Shanghai" |
#### 2.1.2 sysom_server 配置
| **配置项** | **说明** | **默认值** |
| ----------------- | ------------------------------------------ | --------------------------------------------------- |
| path.root_path | 服务端部署目录 | /usr/local/sysom/server |
| db.redis.host | Redis主机地址 | localhost |
| db.redis.port | Redis通信端口 | 6379 |
| db.redis.username | Redis登录用户名 | |
| db.redis.password | Redis登录密码 | |
| db.mysql.dialect | MySQL数据库方言 | mariadb |
| db.mysql.engine | MySQL数据库连接引擎 | pymysql |
| db.mysql.host | MySQL数据库主机地址 | localhost |
| db.mysql.port | MySQL数据库通信端口 | 3306 |
| db.mysql.user | MySQL数据库登录用户名 | sysom |
| db.mysql.password | MySQL数据库登录密码 | sysom_admin |
| db.mysql.database | SysOM数据库名称 | sysom |
| jwt.SECRET_KEY | JWT鉴权秘钥 | \\ |
| jwt.TOKEN_EXPIRE | JWT token 有效时间 | 1728002 days |
| cec.protocol | 通用事件中心协议 | redis |
| cec.topics | 各个微服务对外公告的主题 | \\ |
| cec.special_param | 默认的cec协议特化参数含义见cec开发文档 | \\ |
| cmg.protocol | 通用注册中心协议 | redis |
| logger.format | 日志打印格式 | %(asctime)s | %(levelname)s | %(message)s |
| logger.level | 日志打印等级 | INFO |
#### 2.1.3 sysom_service 配置
| **配置项** | **说明** | **默认值** |
| ----------------------------------- | ------------------------------------------------------------ | ----------------------- |
| path.root_path | 微服务部署目录 | /usr/local/sysom/server |
| service_name | 微服务名称 | sysom_xxx |
| service_dir | 微服务目录 | sysom_xxx |
| protocol | 微服务通信协议 | http |
| host | 微服务部署机器IP | 127.0.0.1 |
| bind | 微服务监听绑定地址 | 127.0.0.1 |
| port | 微服务对外通信端口 | \\ |
| framework | SysomFramework相关配置 | \\ |
| framework.gcache | 通用缓存gcache配置 | \\ |
| framework.gcache.protocol | gcache所用协议 | redis |
| framework.node_dispatch | 节点分发配置结合sysom_node配置使用 | \\ |
| framework.cmg | 微服务治理配置 | \\ |
| framework.cmg.tags | 微服务标签 | \\ |
| framework.cmg.metadata | 微服务元数据 | \\ |
| framework.cmg.check | 微服务健康检查相关配置 | \\ |
| framework.cmg.check.type | 微服务健康检查类型 | http |
| framework.cmg.check.url | 微服务健康检查url | \\ |
| framework.cmg.check.interval | 微服务健康检查周期 | 10 |
| framework.cmg.check.timeout | 微服务健康检查超时时间 | 10 |
| framework.cmg.check.deregister | 微服务注销超时时间如果在deregister指定的时间内所有的健康检查尝试都失败了会将微服务注销 | 25 |
| framework.cmg.check.header | 微服务健康检查请求头部当微服务健康检查类型为http时可以通过本配置传递额外的头部信息 | \\ |
| framework.cmg.check.tls_skip_verify | 微服务健康检查时是否忽略tls证书验证 | false |
| framework.gclient | 通用微服务通信客户端gclient配置 | \\ |
| framework.gclient.protocol | gclient所用协议 | cmg |
| framework.gclient.special_param | gclient协议特化参数 | \\ |
#### 2.1.4 sysom_web 配置
| **配置项** | **说明** | **默认值** |
| -------------- | ----------------- | -------------------- |
| path.root_path | sysom前端部署目录 | /usr/local/sysom/web |
#### 2.1.5 sysom_node 配置
| **配置项** | **说明** | **默认值** |
| ---------------------------------------------------------- | -------------------------------------------- | ----------------------- |
| path.root_path | 节点端部署目录 | /usr/local/sysom/node |
| timeout | 服务端与节点端交互命令的超时时间单位为ms | 60000 |
| envs | 节点端环境配置 | |
| (将脚本下发到节点端执行时可以获取此处定义的所有环境变量) | \\ | |
| envs.NODE_HOME | 节点端部署目录 | /usr/local/sysom/node |
| envs.APP_HOME | sysom应用目录 | /usr/local/sysom |
| envs.SERVER_HOME | sysom服务端部署目录 | /usr/local/sysom/server |
| envs.SERVER_LOCAL_IP | sysom服务端私有IP | 127.0.0.1 |
| envs.SERVER_PUBLIC_IP | sysom服务端公网IP | 127.0.0.1 |
| envs.SERVER_PORT | sysom服务端对外通信接口 | 80 |
| delivery | 节点分发配置 | |
| (添加主机时,微服务可以通过本配置往节点端下发脚本并执行) | \\ | |
| delivery.from_dir | 从何处获取下发资源 | scripts |
| delivery.to_dir | 将文件下发到节点端的什么目录 | node |
| /usr/local/sysom/node | | |
| delivery.files | 微服务要下发到节点端的文件列表 | \\ |
| delivery.files.comm | 架构无关的文件列表 | \\ |
| delivery.files.amd64 | amd64架构相关文件列表 | \\ |
| delivery.files.arm64 | arm64架构相关文件列表 | \\ |
| delivery.files.x86 | x86加购相关文件列表 | \\ |
| delivery.scripts | 映射节点端执行脚本 | |
| (建议此处不做修改,使用默认即可) | \\ | |
| delivery.scripts.prepare | 资源准备脚本 | |
| (目前未用到) | node_prepare.sh | |
| delivery.scripts.init | 节点初始化脚本 | |
| (添加主机时会在节点端执行微服务对应的初始化脚本) | node_init.sh | |
| delivery.scripts.clear | 节点清理脚本 | |
| (删除主机时会在节点端执行微服务对应的清理脚本) | node_clear.sh | |
| delivery.scripts.clear | 微服务健康检查时是否忽略tls证书验证 | false |
| framework.gclient | 通用微服务通信客户端gclient配置 | \\ |
| framework.gclient.protocol | gclient所用协议 | cmg |
### 2.2 SysomFramework 具有那些功能
SysomFramework 目前包含如下功能:
- 日志统一初始化:自动根据配置文件中指定的日志格式和日志等级初始化 clogger
- 分布式缓存SysomFramework 内置了一个分布式缓存底层根据配置可以采用不同的实现默认使用Redis微服务之间可以通过分布式缓存共享状态和数据
- 微服务客户端SysomFramework 提供微服务通信客户端创建接口,只需指定需要与那个微服务通信,即可快速创建一个客户端与目标微服务进行通信,调用者无需关心目标的通信地址;
- 事件中心客户端SysomFramework提供一键创建事件中心客户端Producer、Consumer、Admin的接口无需关注如何传递事件中心的url
- 默认通道任务执行器SysomFramework提供默认的通道任务执行器default_channel_job_executor微服务通过该执行器可以直接与通道模块通信操作纳管节点下发命令下发文件获取文件
### 2.3 如何使用 SysomFramework
#### 2.3.1 初始化
SysomFramework 需要一个 `ConfigParser` 来初始化,因此,首先需要传递**全局配置**和**微服务配置**的路径来初始化一个 `ConfigParser`对象。
```python
##################################################################
# Load yaml config first
##################################################################
YAML_GLOBAL_CONFIG_PATH = f"{BASE_DIR.parent.parent}/conf/config.yml"
YAML_SERVICE_CONFIG_PATH = f"{BASE_DIR}/config.yml"
YAML_CONFIG = ConfigParser(YAML_GLOBAL_CONFIG_PATH, YAML_SERVICE_CONFIG_PATH)
```
接着在微服务程序的入口(注意是微服务程序的入口,不要在诸如 django 的 view 视图等可能被创建和调用多次的地方调用)出调用下列方法进行初始化:
```python
from sysom_utils import NodeDispatcherPlugin, CmgPlugin, SysomFramework
SysomFramework.init(settings.YAML_CONFIG) \ # 初始化 SysomFramework
.load_plugin_cls(NodeDispatcherPlugin) \ # 如果微服务需要下发文件到节点端执行这行
.load_plugin_cls(CmgPlugin) \ # 启用微服务治理(默认开启)
.enable_channel_job() \ # 初始化 default_channel_job_executor
.start() # 启动 SysomFramework
```
#### 2.3.2 分布式缓存
```python
from sysom_utils import SysomFramework
# 创建或者接入一个名为 cache1 的共享缓存
g_cache = SysomFramework.gcache("cache1")
# 存储
g_cache.store("name", "able")
# 获取
name = g_cache.load("name")
# 删除
g_cache.delete("name")
# 清空缓存只会清空创建gcache对象时指定的缓存此处会清空名为 "cache1" 的缓存)
g_cache.clean()
```
#### 2.3.3 微服务客户端
```python
from sysom_utils import SysomFramework
# 创建一个 GClient 用于访问 sysom-api 服务
g_client = SysomFramework.gclient("sysom_api")
# 调用 sysom-api 服务的接口获取主机列表
res = g_client.get("/api/v1/host/")
# 输出主机列表
print(res.json())
```
#### 2.3.4 事件中心客户端
- Producer 示例
```python
import time
from sysom_utils import SysomFramework
# 通过 SysomFramework 快速创建 Producer无需指定地址
producer = SysomFramework.cec_producer()
# 测试每秒生成一个事件,持续 10000 秒
for i in range(10000):
# 生成一个事件并注入到主题 'this_is_a_test_topic' 当中
producer.produce("this_is_a_test_topic", {
"hehe": i
})
# 强制刷新,保证生产事件是同步的,前一个事件成功投递到事件中心
# 才会开始投递下一个事件
producer.flush()
time.sleep(1)
```
- Consumer 组消费示例
```python
from cec_base.consumer import Consumer, dispatch_consumer
from threading import Thread
from sysom_utils import SysomFramework
# 通过 SysomFramework 快速创建 Consumer无需指定地址
consumer = SysomFramework.cec_consumer("this_is_a_test_topic")
for msg in consumer:
print(f"{msg.message_id} => {msg.value}")
# 消息处理完之后需要进行消息确认
consumer.ack(msg.message_id)
```
## 3. 快速创建微服务
进入到 `script`目录,执行下列方法快速创建微服务
```bash
# 使用方式
# <微服务名>:不带 sysom_ 前缀,会自动拼接,不能与现有的服务同名(冲突会有提示)
# <微服务端口>:不能与现有的服务冲突(冲突会有提示)
./sysom.sh create server <微服务名> <微服务监听端口>
# 使用示例 => 下列命令会一键创建一个名为 sysom_demo 的微服务,并监听在 7010 端口
./sysom.sh create server demo 7010
```