构想
简易 OJ 的一些构想
想了一下,几乎全是数据库,crud,感觉在做上个世纪的破事(×)
还没开始实现,所有构想都是口嗨,一些细节可能考虑不周。
也算是磕磕绊绊把一些基础的 spring 学完了,找资料简单看了一些全家桶,技术栈上应该除了两个标黄的内容都差不多了。
数据库
用 mybatis + mysql ,spring 提供了 mybatis 的集成,用起来非常方便。
登录认证,权限
用 spring security:
加密用 Bcrypt 随便瞎搞一下
认证用基础的 name-password-sessionCookie 做认证,以下来自哈基米(×):
一句话结论:不要为了由于所谓的技术潮流而上 JWT,对于一个仅需邮箱登录的 OJ,Session/Cookie 依然是统治级的最佳实践。
链路认证和方法认证,spring security 都提供了完备的实现(我爱 spring!)
权限管理未解决
权限管理需要细化,简单的线性 role 表不行,需要学习role hierarchy,制作有继承关系的权限管理。
数据存储
我想拿 alist 搞一个云盘出来,或者直接存服务器本地,然后数据库挂文件路径读文件。
各种数据
一个题面的数据schema
- 题面.md
- 数据包:
- 一个 yml 配置数据列表,评测限制
- 数据实例 in out
- 如果有 specialjudge,需要 checker.cpp
- 应该没了?
可以仿照 polygon 包装一个支持 testlib 的。
评测记录schema(未确定)
想不动了,先鸽着。
个人界面(未确定)
头都大了,要一堆东西。
评测系统
未解决
有两个方案:
- 搓一个,JVM 有线程管理工具,能挂 cgroup/namespace 做资源隔离,不过这个我不确定能否高性能,况且我只是了解过有这个东西,完全没有手操过。和 cf 一样采用的每个核跑一个评测(应该也只能这么做?),对我这个 单U 8核 来说比较灾难,分布式的话一是没钱,二是不会配(哭。
- 用开源的,比如 青岛U,domJudge,但得学,不会配。
实在没时间搞就写个最简单的:只支持 c/c++,直接命令行搞,系统隔离统统不用,能跑就行。
后端交互
通信用 kafka ,随便设计一个做交互就可以,测完结果直接存数据库。
具体来说的话,数据库只用来挂文件路由,可以在提交给 kafka 前就写好,然后评测机不需要和数据库交互,根据文件路由直接改文件就可以了。
读的话通过数据库找路由,直接读,这里可能会有线程同步的问题,不过应该问题不大?因为我也没必要完全和当前评测相吻合,读的时候缺一个少一个没啥影响,最后能全测完就可以了。
有一说一,我多线程就没怎么看,算不上精通吧,只能说一点不会,所以说的很口嗨。
应该是个丑陋的实现()
前端交互
指如何把评测结果返回给前端。
作为 demo 自己刷新轮询就行了,websocket 是不会配的。
轮询的话,直接查数据库,再挂个提交记录的表,提交记录,也搞进文件存储,提交记录挂数据库去抓。
前端
AI 写一个,手搓是不可能的,写后端已经够累了。
比赛
这个应该得等大作业交完差后再实现了,需要重构一些底层。
一是权限管理太简易了,是线性权限,如果给每一个比赛都加一个 contest+id 的权限,那数据库得丑的不行,需要一些树状的继承形权限。
二是对提交记录的查询需要更新,比赛和做题对同一个提交记录的展示是不同的,例如数据点,评测细则这些就不能在比赛时展示,赛后可以展示。
三是比赛的种类多,NOI 赛制下需要部分分,xcpc 需要罚时和封榜,这需要多一些判题逻辑。
进一步
数据库可以看情况做个缓存,不过 demo 上直接先查询也是可接受的。
网关,反代没有,要不就 Nginx 要不就 spring cloud gateway。
系统监控,不会。
vault 做个密钥管理。
servlet MVC 用线程池挂请求,高并发估计会爆炸,有机会试试异步 MVC。
别的,再看?
到时候还能把多模块配置挂到 git 上,用 spring cloud config 来读。

浙公网安备 33010602011771号