前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Phoenix框架 从0到1设计业务并发框架 自动构建有向无循环图设计

Phoenix框架 从0到1设计业务并发框架 自动构建有向无循环图设计

原创
作者头像
Meng小羽
发布于 2024-05-13 03:47:49
发布于 2024-05-13 03:47:49
1620
举报
文章被收录于专栏:Debug客栈Debug客栈

从 0 到 1 设计业务并发框架系列:

Phoenix 自动构建有向无环图的业务并发框架,核心就在于不需要开发人员关心调用分层和依赖互斥的排序问题,通过算法进行自动构建、收集 Task 任务、检测环或者依赖,最后打印并发组分层信息。

本篇文章就讲解下如何构建有向无环图的设计实现方案及遇到的问题。

实现方案

有向无环图的构建采用的是设计模式中的策略模式,首先定义好 Builder 的实现方式,如下:

代码语言:java
AI代码解释
复制
/**  
 * @author debuginn  
 */
public interface PhoenixBuilder {  
  
    // 过滤 Phoenix API 使用到的 Task 任务  
    Map<String, ArrayList<TaskObj>> filterApiUsedTask(ArrayList<TransObj> transObjArrayList);  
  
    // 根据 api 获取需要执行的 trans    
    Map<String, ArrayList<TransObj>> apiTransMap(ArrayList<TransObj> transObjArrayList);  
  
    // 是否存在依赖关系  
    void isHaveLoop(Map<String, ArrayList<TaskObj>> apiUsedTaskMap);  
  
    // 处理并发组分层划分  
    Map<String, ArrayList<ArrayList<TaskObj>>> processConcurrentGroup(Map<String, ArrayList<TaskObj>> apiUsedTaskMap);  
  
    // 打印并发组分层信息  
    void printConcurrentGroup(Map<String, ArrayList<ArrayList<TaskObj>>> phoenixApiArrayListMap);  
}

PhoenixBuilder 需要实现 6 种方法:

  1. 首先,将收集上来的 Task,按照 API 进行分组,Task 存在依赖调用的都进行收集;
  2. 按照 API 进行收集 Trans,后续 Trans 使用请求线程进行串行执行;
  3. 判定每个 API 收集上来的 Task 是否存在相互依赖或循环依赖;
  4. 将每个 API 收集上来的 Task 按照先后依赖关系进行分组划分;
  5. 打印并发分组信息,用来给开发者调试及校验使用;
划分并发调用组
划分并发调用组

由于存在依赖关系,需要进行分层设计,这里可以结合 Phoenix 框架 怎么组织设计一个框架 来看,然而每一层并不需要关系执行的顺序问题,这里采用了最简单的数据结构存储分层信息,Map<String, ArrayList<ArrayList<TaskObj>>> Key 用来标识属于哪个 API 请求的并发分组,Value 则采用最简单的二维数组进行存储,每一维分别存储需要进行执行的 Task 任务。

遇到的问题

怎么判定存在环

由于我们要进行构建的是有向无环图,那么存在相互依赖的 Task,在框架设计逻辑中是行不通的,若存在相互依赖,那么究竟该先执行哪个 Task 呢?

依赖关系
依赖关系

可以看到上图,只要有两个场景:

  • 相互依赖关系:TaskB 与 TaskD 存在相互依赖,那么就不能确定执行顺序;
  • 环状依赖关系:TaskD、TaskF、TaskG 和 TaskE 存在依赖环,也无法确定执行顺序;

相互依赖关系判定比较简单,就是检索一个 TaskA 依赖的 TaskB 是不是也依赖这个 TaskA,

循环依赖判定相对来说比较复杂,需要遍历图的所有路径,若路径存在闭环,则代表着存在环,反之,就是不存在环路,代表就是单向依赖的分支路径。

怎么划分并发分组

划分并发分组,就是将彼此没有依赖关系的 Task 按照依赖的先后顺序进行分组,其实就是按照图的深度遍历。

这里的遍历,由于有依赖关系,可以采用向上遍历或者向下遍历的方式,我们采用了压栈的方式处理:

向上遍历
  • 首先找到没有被依赖的 Task,这是一组,之后存入数组压入栈底;
  • 之后栈底的 Task 收集出来需要依赖的 Task,这些收集上来的 Task 需要再判定是不是被其他 Task 依赖,若是依赖的话,则保存在临时的 Task 数组中,最后将剩下 Task 就是只被栈底 Task 数组依赖的 Task,那么将这个分组继续压入栈内;
  • 重复第 2 步,把栈底的 Task 换成栈内最上层的数组,之后再把临时 Task 追加到收集出来需要依赖的 Task 上,去重,之后重复执行;
  • 最后执行到剩下的 Task 没有依赖的 Task,这就是最后一个并发组,之后压入栈内;

最后程序执行的时候,就是先执行栈顶部的并发组,之后一次出栈执行。

向下遍历
  • 首先找到不依赖其他 Task 的 Task,这是一组,之后存入数组压入栈底;
  • 之后栈底的 Task 收集出来依赖这个分组的 Task,这些收集上来的 Task 判定是不是被其他 Task 依赖,若是依赖,也是保存在临时的 Task 数组中,最后就只剩下只依赖栈底的 Task 数组的 Task,之后将这个数组压入栈内;
  • 重复第 2 步,把栈底的 Task 换成栈内最上层的数组,之后再把临时 Task 追加到收集出来需要依赖的 Task 上,去重,之后重复执行;
  • 最后执行到剩下的 Task 没有任何 Task 依赖,这就是最后一个并发组,之后压入栈内;

此时,这个堆栈存储的是最先执行的 Task 并发分组在栈底,最后执行的在栈顶,需要进行反转操作,之后再依次进行执行。

为何要使用"策略模式"

在开发程序的时候,大家都不约而同地讲究程序的横向扩展能力,将核心的关键的任务拆分成具体执行的子任务,这样不仅可以提高程序的可阅读性,而且还可以扩展不同的遍历算法,用来后续框架的持续优化。

不仅这里,Phoenix 框架尽可能的采用策略模式实现,将核心功能点都进行拆分,做到模块化设计,这样的设计正是 Phoenix 框架的设计初衷,生生不息,持续迭代。

写在最后

本篇文章主要讲了如何进行自动构建有向无循环图的思路及遇到的问题,其实在开发中,这种解决依赖关系的场景还有很多,其实抛开上层的业务实现或者框架需求来看,底层就是最基本的数据结构,算法,图的遍历场景在当今比较火的 AI 场景下也是如此。

感谢你的阅读,你要是有好的方案或者好的 idea 可以与我一起交流,最后,如果你感兴趣,推荐关注公众号或订阅本站,欢迎互动与交流,让我们一起变得更强~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
使用 Docker 搭建 Seafile 私有云流程记录
自之前的那篇静态文章 “Docker 安装 Seafile 私有云记录” 丢失后就一直搁置,这之间因为各种原因在服务器和本地都来回重装了几次,那么今天就简单来聊下这个私有云的搭建流程,也当做个记录了(@一下催更本文的Ying酱/滑稽)
2Broear
2024/03/12
1.4K0
使用 Docker 搭建 Seafile 私有云流程记录
云同步网盘-seafile
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/09/17
5.6K0
Seafile-开源企业云盘和文档协作平台
这些功能的结合使得Seafile成为一个协作流畅、可控和高效的工具,助力团队在共享文件和协作过程中取得更好的效果。无论是小型团队还是跨部门合作,Seafile都能提供强大的共享协作支持,促进团队的协同工作和创造力。
huolong
2024/03/02
7610
Seafile开源私有云自定义首页Logo图片
一 在启动页面找到logo的地址有两处 /opt/seafile/seafile-server-7.1.5/seahub/frontend/src/assets/seafile-logo.png /opt/seafile/seafile-server-7.1.5/seahub/media/img/seafile-logo.png 二 利用挂载把他们顶掉即可 version: '2.0' services: db: image: mariadb:10.1 container_name:
ydymz
2021/01/05
1.6K0
Ubuntu 搭建 Seafile
本文档用来说明通过预编译好的安装包来安装并运行基于 MySQL/MariaDB 的 Seafile 服务器。(MariaDB 是 MySQL 的分支)
木制robot
2018/10/09
3.6K0
seafile配置全文搜索
可以在 seafevents.conf 中设置 [INDEX FILES] 选项来控制文件搜索的行为。你需要重新启动 seafile 和 seahub 使它们生效。
鹏程
2023/07/24
1K0
docker安装seafile
项目需求 使用seafile搭建一个内网网盘 安装过程 官方给的例子如下: https://docs.seafile.com/d/cb1d3f97106847abbf31/files/?p=/dock
2023/07/04
7190
sentry部署整理 原
sentry是python开发的一个应用,使用python uWSG框架运行,所有安装完sentry要记得在nginx的代理上禁用掉/admin路径,不然uwsg的后台管理入口就泄漏了 具体的安装资料地址为:
domain0
2018/08/01
2.2K0
在Ubuntu 16.04上安装Seafile并配置Nginx
Seafile是一个跨平台的文件托管工具,包含了适用于Linux和Windows的服务器应用程序,以及适用于Android,iOS,Linux,OS X和Windows的GUI客户端。它支持文件版本控制和快照,双重身份验证,WebDAV(Web-based Distributed Authoring and Versioning),并且可以配合Nginx和Apache使用以启用HTTPS。
Techeek
2018/09/06
4.2K0
使用Seafile搭建个人专属私有云盘
Seafile是一款强大优秀的云同步软件,拥有跨平台文件同步、移动端文件访问、挂载盘、文件共享和权限控制、文件锁定、文件版本管理和资料库镜像、在线编辑和协同编辑、审计日志等功能。下面演示一下该软件安装步骤。
兔云小新LM
2021/01/04
11.9K0
使用Seafile搭建个人专属私有云盘
手摸手一小时从0搭建专属个人博客(视频教程)
视频地址: https://www.bilibili.com/video/BV1xz4y1k783/
一行Java
2022/04/07
2750
手摸手一小时从0搭建专属个人博客(视频教程)
Docker快速部署一个属于你自己的博客
对于 solo 这个博客系统,至少需要部署 3 个 docker 容器。 mysql 用来存储、 solo 就是博客系统、nginx 用来做反向代理以及 http 到 https 的跳转。
ppxai
2020/09/23
7520
玩转NAS | VS Code网页版IDE,每个程序猿必备一套!
最近在逛Github的时候发现了一个66.3k star 项目code-server ,感觉实在有点相见恨晚 💝,它是一个在浏览器中运行VSCode的开源项目,让开发者随时随地的进行Coding,乃至于手机、平板上进行远程开发,给开发者带来了极大的便利。
全栈工程师修炼指南
2024/07/06
9350
玩转NAS | VS Code网页版IDE,每个程序猿必备一套!
Minio对象存储
多节点的Minio会根据不同的Access_key及Secret_Key来区分不同租户,每个租户可操作对应Server获取Object。Minio Server间可以通过不同的进程模型、容器或是虚拟机来互相隔离。
仙人技术
2020/04/29
9.1K0
Minio对象存储
Docker获取Let`s Encrypt SSL 证书
为了方便维护、升级,同时也避免破坏本地的开发环境,我这里使用docker方式来运行certbot。整个过程分为两步:首次申请证书和证书更新。
孟斯特
2023/11/15
8940
一键配置 Seafile 云盘并开启 https 访问
前些日子终于受够了臃肿的 Nextcloud ,将其完全卸载,寻觅已久之后选择了 Seafile 云盘。之所以放弃 Nextcloud,大致有以下原因:
宋天伦
2020/07/16
4.6K0
Nexus3最佳实践系列:搭建Docker私有仓库
容器仓库是容器化管理中非常重要的一环,相当于 SVN 在程序研发、运维发布中的地位。因此,一个稳定、可靠的容器仓库尤为重要。
张戈
2018/10/10
14.6K0
app管理平台 app-host
一个轻量级的包托管网站,app-host 主要用于 iOS 和 Android 的包管理,作用类似于fir.im,不同之处是可以自由部署在内网,方便了公司项目保密。并且代码开源也可以方便根据各自需求进行定制化开发。
iginkgo18
2021/07/07
3.3K0
自建Docker镜像加速服务
陳斯托洛夫斯記
2024/08/07
5220
提升运维效率:轻松掌握JumpServer安装和使用技巧
还不会在局域网申请 ssl 及配置的可以参考之前的文章 前后端都用得上的 Nginx 日常使用经验
易墨
2023/11/11
3K0
提升运维效率:轻松掌握JumpServer安装和使用技巧
推荐阅读
相关推荐
使用 Docker 搭建 Seafile 私有云流程记录
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档