Appearance
查询程序改造
作为曾经开发的心血之一,现有的单体框架查询程序是完全满足要求的,设计目标每小时能查询一万名玩家的数据,实际差不多 5000 次的时候就会触发单账号的限制,一般是稳定在 3000 次左右
思考
- 需要完成一主多从和回落机制的改造
- 数据库选型:mysql,minio,mongodb,prosgresql+ts 列压缩。需要考虑怎么方便的切换主从地位和进行同步。根据测试结果还是使用传统 mysql
可惜随着时过境迁,现在遇上了一些问题
- 单体架构无法实现复合查询:由于一开始只关注了单机对 GTA 的查询,目前查询代理没法拓展给多机或者是给 GTA、荒野大镖客 2 等服务一起使用
- 单用户结构存在问题:目前最大也是最头疼的问题就是这个,无法查询主机服务、查询程序下线都是因为 R 星对于用户级别的限制限制了
- 数据库未做文件改造:目前为了实现准确的规则匹配,我把查询时的快照保存了一份,当时没考虑到未来的数据量巨大,现在单表接近 60G
- 结构臃肿:由于共享的工具比较多,当时又没有合理的 CICD 概念,因此单个代码库里混杂了查询程序、WEB 服务器、定时调度、数据共享服务器等太多项目,需要简化
- 由于为了方便管理,WEB 前端框架用的 docsify,优点是部署起来方便快捷,缺点就是由于是 SPA,所以没法被搜索引擎收录。我得自己写一个 SSR 方案
- 查询程序仓库
- 查询程序
- WEB 服务器
- 限速模块
- 定时调度
考虑了一下,按照顺序抽象了如下几个任务
- 代理模块独立抽离
- 多用户查询化改造
- WEB 服务异步和多线程支持
数据库快照存储抽离是一个相对独立且复杂的改造,我得研究一下到底是文档数据库好还是对象存储合适,尤其是单表行数可能超过千万级别。反正现在 mysql 全库统计一次半个小时跑不完我是完全无法接受的
- TODO
- [ ] 代理服务模块
- [ ] 数据缓存模块
- [ ] 池化调度器
- [ ] WEB 服务器优化和 SSR
- 杂项
- [ ] 奖章分类自动化
代理模块抽离部分
这部分的比较简单,先抽离出来独立做一份,也顺便发一篇文章。结果最近一直在忙,不知道什么时候可以搞定
多用户查询改造
得给当前的查询程序做一个大手术,数据获取和写入依旧是使用数据库,但是调度需要把代理部分的控制模块移除,然后添加上多账号共同使用和单个 ID 的并行查询加速。感觉基本上就是需要重写一份调度方案了。应该可以复用现有的代理模块
WEB 服务器异步、WebSocket 和多线程支持
这个有点麻烦,原本服务器使用的是 Python 里很标准的 Nginx + Gunicorn + Flask 技术栈。但是 Flask 不支持性能比较高的异步操作,这对 Web 服务器的性能有一定影响(问题不大,异步有利有弊)
更糟糕的是 Gunicorn 是进程调度模型,没有主模块做调度,没法接入一个简单的限速模块,暂时了很久的解决方案是 ugly 的单独起了一个缓存程序。这就需要研究一下到底该怎么处理了,也许可以用代理模块的流控实现一个缓存模块
目前查询程序还需要优化的一个点是目前的模型是同步轮询,也就是说带来了大量的重复请求。每次查询都得反复拉取好多次,不如做一个异步通讯改造,这样更新数据就只需要一轮操作了
当然这样也存在需要改造客户端以及修改 QQ 和微信的服务端的问题。还有一个更加麻烦的点在于支持 websocket 的 uvicorn 是单线程异步模型,虽然不会被并行访问限制住,但是又会被同步 IO 击毙(比如数据库查询和内部请求之类的,这些不好异步化改造),如果使用 gunicorn+uvicorn 这样套又感觉太过憨批了
当前架构分析
初步完成了一个简单的架构绘图,这个是使用 mermaid 画的逻辑调用顺序操作图,实际隐藏了大概 3-5 倍的实现细节
现有程序逻辑
整理了一下一个简单的请求方式,需要考虑如何调用服务(socket?http?websocket?)以及拆分服务依赖以后如何解决上游宕机后下游无法使用的问题
目前分析了一套之后准备开发两个基础设施,一个是能够通过 socket 和 http 协议通讯的套件,起到类似 serverless 函数的触发器的功能,将内网的调用方式做统一。还有一个是在通讯套件的基础上进行二次开发,集成服务发现、消息队列、异步队列触发器等功能的控制平台,将内网服务串联。目前在考虑如何设计一个足够健壮的架构,能够在本身不停机的情况下动态加入和退出新的服务
还有关于目前工作进度的思考,基础设施基本上定型了(花了太多钱,也暂时换不起了),目前在研究冷却怎么搞。硬件暂时也不是必须更换(zen5 的单核进步巨大,在考虑和 14 代比,急不来)。内网能力梳理其实做了很久了,但是怎么整合还是一个问题
其实内网能力梳理和程序逻辑设计之间有很大关系,都需要考虑需要哪些能力,通过什么方式调度和传输。目前在学习《凤凰架构》和《微服务架构设计模式》,这两本书基本上把微服务是什么、怎么做完完全全的给你掰开了,揉碎了讲。两本加起来 100 块钱,比之前看的那本基础设施及服务的强多了
网络方面不确定要怎么改造,这个一方面是需要改硬件,另一方面也涉及到需要将国内外的几台服务器、个人网络、手机等设备共同组网,内网做统一的监控和审计
新查询程序的结构设计
- 抽象节点
- 代理模块:代理池,负责管理代理请求
- 调度模块:负责管理查询对象的限速、续期和适配处理
- 管理模块:负责管理调度模块
- 通用组件
- log 显示和持久化模块
- 数据湖 cache 和持久化模块
- 数据传递和传出模块
- 限速计算模块?
- 模块统一接口
- metrics
- 输出运行状态
- 日志输出接口
- 信息输入接口(触发处理)
如何设计架构是一个问题
首先需要一个调度器来调度各种查询器,查询器内置认证模块,把请求委派给代理池。还是认证模块作为代理模块的子模块,实现统一的能力封装,兼容更多模块?
这样就有一个问题,如果每个查询器都有一个调度器,那么代码复用一定是一个问题。如果一个调度器调度所有的查询器,那么查询器更新了就会影响到调度器,非常麻烦。该如何管理呢?
更加麻烦的是,查询器和代理池都需要实现单独的暂停机制,怎么设计消息传输,怎么传输数据都是一个问题
- QA
- cookies 需要更新或代理需要暂停的话,请求队列该如何回滚。保留可用还是直接抛弃?还是判断更新后就尝试重新请求?
- 该如何完成模块暂停和整体调度暂停回滚
- 如何进行单独调度模块的动态更新和调度(通过多进程的方式?子进程动态导入)
- 是否通过消息队列来进行数据传输,避免热加载问题?
- 如何注入依赖,包含配置文件和日志、handler等组件
- 如何管理程序,客户端独立打包还是服务端统一管理,如何缩扩容