文章目录
- 背景
- 改造方案
- 新架构图
- 技术选型
- 思考
- 服务拆分
- 公共组件设计
- 自部署算法服务
- 排期计划
- 全球多活改造
- 背景
- 架构图
- 分布式ID
- 大表分区处理
- 范围
- 使用用途
- 改造方案
- 排期计划
- 升级预算
背景
1、xx业务经过多轮的业务决策和调整,存在非常多技术包袱,带了不好的用户体验和极高的维护成本
2、多套机房部署,服务部署复杂,性能可靠性无法保证
3、多套后端接口,前端接入标准不统一,通用逻辑不一致(扣费、试用、商业化)
4、主要维护业务基于g0实现,服务类型为http无状态服务,部署在美西k8s集群,具备单机房的弹性伸缩能力,服务的高可用可以进一步提升;单机房,欧洲、亚洲用户访问服务存在慢的问题
5、缺失前后端通用业务组件设计,复用性不高
缺失服务端调用链路监控与跟踪;
部分表存在单表过大问题,超5千万量级。
背景总结:
业务的调整,合并多个服务,前端接入多套后端接口,通用的扣费、试用等逻辑不一致,所以服务拆分,以及需要做统一的微服务网关;
之前是多个单机房单体应用,需要提高服务的高可用,以及数据的高可用;
改造方案
新架构图
技术选型
项目 | 技术选型 | 集成能力 |
---|---|---|
xx服务网关 | Traefik | 用户鉴权、限流器 |
go框架 | goframe |
思考
对于微服务网关的调研,为什么选用这个云原生网关,跟传统网关的区别,以及这个网关服务跟普通服务有什么区别?
服务拆分
序号 | 服务 | 代号 | 拆分定义 | 技术选型 |
---|---|---|---|---|
01 | 服务网关 | xx-gateway | xx全流量网关,支撑xx全部业务流量,提供用户鉴权、限流器、微服务转发基础能力 | Traefik |
02 | 接入层 | xx-api | 负责xx产品所有API的注册、参数验证、服务调度 | goframe |
03 | 用户服务 | xx-usersrv | 主要负责用户相关业务服务提供 | 主要包含 授权、积分、产品管理模块 |
04 | 应用服务 | xx-appsrv | 主要负责xx业务服务能力提供,主要包含 1、编辑器 2、轻编辑 3、工具箱(媒体处理、AI生成)4、存储服务(凭证、签名、转存、删除、分享) | goframe |
05 | 用户运营管理后台 | xx-admin | 提供xx整理业务运营数据可视化呈现、运营配置、权益流水等 | Dcat Admin(php) |
公共组件设计
序号 | 组件 | 职责 |
---|---|---|
01 | 外部服务调用SDK | 统一封装外部服务的SDK组件,整合公司中台依赖所有服务,只负责网路请求,重试,相关错误返回给调用方 |
02 | 任务组件服务 | 统一封装任务组件,支持分布式,实现重试、延迟、定时、回调、任务记录、任务编排相关能力 |
自部署算法服务
各种算法的部署+ 有个中间服务调度算法任务
例如 视频压缩算法的调用:
排期计划
序号 | 项目 | 责任人 | 预计上线时间 |
---|---|---|---|
01 | 整体架构文档方案输出 | One Two | |
02 | 代码拆分改造(接入层、用户服务、 应用服务、构建发布改造搭建) | One | |
03 | 服务结构拆分、配置分离、boot、vars、components结合作组件初始化、组件配置化 | One | |
04 | 服务网关的搭建 | One Two | |
05 | 基础组件搭建,抽出基础组建层,定义相关标准 | Three | |
06 | 基础组件搭建,外部云服务SDK封装 | Three | |
07 | 基础组件搭建,任务通用组件封装 | One Two | |
08 | 基础组件搭建,其他通用组件封装 | Three | |
09 | IBM服务替换接入云平台新接口 | Three | |
10 | 接入层代码逻辑迁移 | Three | 阶段1改造:6月底,目标:完成框架搭建、完成组件库建设、完成IBM能力的迁移承接 |
11 | 用户服务和应用服务代码迁移,逻辑改造(服务级的调用方式) | Two Three | |
12 | 数据库的拆分(用户库、应用库) | Two | 阶段2改造:7月中旬,目标:完成微服务架构的改造 |
13 | 服务网格接入 | Two | |
14 | 全局流量管理开发,整体架构多活适配改造与验证 | One | |
15 | 全球多活节点部署 | One | |
16 | 部分流量的验证 | One | |
17 | 全部流量的上线 | One | 阶段2改造:7月底,目标:完成全球多活架构的应用 |
全球多活改造
背景
仅美西一个机房节点提供服务,欧洲|、亚洲用户访问xx服务响应服务慢,影响用户体验;
部分表存在单表过大问题,超5千万量级。
架构图
美西作为中心节点,使用DTS双向同步其他节点数据库
每个机房可设置一个私有库,不做同步,用于存储隐私数据相关
美西机房设置ECS从库,用于灾备用途
分布式ID
所有的业务表更改ID属性,取消自增ID,更改为分布式ID,用于解决ID主键冲突的问题。
第一阶段:修改表ID属性
alter table activity modify id bigint unsigned NOT NULL ;
alter table share_reports modify id bigint unsigned NOT NULL ;
alter table share_reports modify share_id bigint unsigned NOT NULL DEFAULT '0' COMMENT '# 分享ID';
alter table ab_cate modify id bigint unsigned NOT NULL ;
alter table products modify id bigint unsigned NOT NULL ;
alter table feedback modify id bigint unsigned NOT NULL ;
alter table products_store modify id bigint unsigned NOT NULL ;
alter table system_configs modify id bigint unsigned NOT NULL ;
alter table portrait_categories modify id bigint unsigned NOT NULL ;
...
采用开源的雪花算法生成分布式ID,参考链接:https://github.com/bwmarrin/snowflake
分布式ID生成单独放在公共服务里生成
修改业务,手动控制插入表的ID的值,用GORM的callbck事件实现
数据平滑过渡:https://www.zhihu.com/question/391373815
大表分区处理
范围
库:xxx_api
表:tasks、resources
CREATE TABLE `tasks` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`task_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 任务ID',
`type` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 任务类型',
`subtype` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 任务子类型',
`params` json DEFAULT NULL COMMENT '# 参数',
`status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '# 状态: 1创建失败 2执行中 3成功 4失败 5关闭 6超时',
`ws_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# WS_ID',
`take_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 理论耗时',
`spend_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 真实耗时',
`estimate_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 预估耗时',
`download` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 下载次数',
`device` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 移动设备: 0未知 1PC 2WAP',
`ip` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# IP',
`err_msg` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '# 错误描述',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deduction` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否扣费:0否 1是',
`srv_params` json DEFAULT NULL COMMENT '# 服务参数',
`offline` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否离线:0否 1是',
`vip` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# VIP:0-否, 1-是',
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 产品ID',
`bucket` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# oss的bucket:0美西 1乌兰 2dx',
`offline_task` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否离线处理任务:0否 1是',
`offline_email` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 离线任务接收邮箱',
`offline_send` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否发送邮件:0否 1是',
`offline_unread` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否更新未读:0否 1是',
`display` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否展示:0否 1是',
`preview` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否预览任务:0否 1是',
`external` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 第三方标识,0中台 1阿里云 2dx的pixpic',
`template` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 模板',
`step` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 分步',
`lora_id` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# lora模型id',
`verify_kind` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 权益',
`platform` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 平台',
`version` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 版本',
PRIMARY KEY (`id`) USING BTREE,
KEY `tasks_ws_id_index` (`ws_id`) USING BTREE,
KEY `tasks_status_index` (`status`) USING BTREE,
KEY `tasks_task_id_index` (`task_id`) USING BTREE,
KEY `tasks_created_at_index` (`created_at`) USING BTREE,
KEY `tasks_type_index` (`type`),
KEY `tasks_subtype_index` (`subtype`)
) ENGINE=InnoDB AUTO_INCREMENT=41056984 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='# 任务表';
CREATE TABLE `resources` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ws_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# WS_ID',
`task_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 任务表ID',
`task_type` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 任务类型',
`task_subtype` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 任务子类型',
`meta` json DEFAULT NULL COMMENT '# 文件元信息',
`url` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 文件访问地址',
`expired` timestamp NULL DEFAULT NULL COMMENT '# 文件过期时间',
`status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '# 状态: 0无效 1有效',
`source_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 资源类型: 0其它 1输入资源 2输出资源',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`is_delete` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 是否删除:0否 1是',
`name` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 名称',
`format` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '# 输入格式',
`size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 原始大小',
`bucket` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 地区:0美西 1乌兰',
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '# 产品ID',
`external` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '# 第三方标识,0中台 1阿里云',
`detail` json DEFAULT NULL COMMENT '# 补充信息',
PRIMARY KEY (`id`) USING BTREE,
KEY `resources_ws_id_index` (`ws_id`) USING BTREE,
KEY `resources_task_id_index` (`task_id`) USING BTREE,
KEY `resources_created_at_index` (`created_at`) USING BTREE,
KEY `resources_task_type_index` (`task_type`) USING BTREE,
KEY `resources_expired_index` (`expired`) USING BTREE,
KEY `resources_format_index` (`format`),
KEY `resources_task_subtype_index` (`task_subtype`),
KEY `resources_url_index` (`url`)
) ENGINE=InnoDB AUTO_INCREMENT=87350171 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='# 资源表';
使用用途
任务记录
任务输入输出资源记录
主要查询场景
1、where task_id=xxxxx and xxx
2、where ws_id=xxxx and xxxx
改造方案
- 1、task表:
增加分区字段part_id bigint类型,注册用户分区字段写入wsid, 临时用户分区字段写入时间年月:202403
增加full_task_id,基于taskid+分区字段拼接,如:taskid: ead-6a038265-175e-4d4f-92a6-88aa93014493 part_id: 336736560,拼接后的full_task_id: ead-6a038265-175e-4d4f-92a6-88aa93014493_P336736560
full_task_id 会暴露给外部,基于full_task_id mi服务自动解析出 part_id 和 taskid
增加字段:
ALTER TABLE mediaio_api`.`tasks
ADD COLUMN full_task_id`varchar(180)NOTNULLDEFAULT''COMMENT '# 全信息taskid',`
ADD COLUMN part_id`bigintUNSIGNED NOT` `NULL` `DEFAULT` `0 COMMENT'# 分区ID'`,
DROP PRIMARY KEY``,
ADD PRIMARY KEY (id,part_id) USING BTREE;
ALTER TABLE `mediaio_api`.`tasks` PARTITION BY HASH (part_id)
PARTITIONS 191
;
创建分区:
- 2、resources表,基于task_id hash分区
变更字段
ALTER TABLE `mediaio_api`.`resources`
MODIFY COLUMN `task_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '# 任务表ID' AFTER `ws_id`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`, `task_id`) USING BTREE;
创建分区
ALTER TABLE `mediaio_api`.`resources` PARTITION BY HASH (task_id)
PARTITIONS 383
;
- 3、 users 表
变更字段:
ALTER TABLE `mediaio_api`.`users`
MODIFY COLUMN `ws_id` bigint(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '# WSID' AFTER `password`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`, `ws_id`) USING BTREE;
创建分区
ALTER TABLE `mediaio_api`.`users` PARTITION BY HASH (ws_id)
PARTITIONS 191
;
排期计划
序号 | 项目 | 责任人 | 预计上线时间 | 备注 |
---|---|---|---|---|
01 | 数据拖敏 | 1d | Two | |
02 | 分布式ID改造 | 1d | Two | |
03 | 全局路由流量跨机房异常兼容 | 3d | Three | 范围:1、任务状态轮询 ; 改造方案:1、出现夸机房流量,当redis没有命中,需要使用mysql记录作为兜底,保证业务接口正常。 |
04 | 大表分区处理 | 3d | One | |
05 | 单元节点部署验证 | 5d | One |