【负载均衡式在线OJ】oj_server模块

程序源码

https://gitee.com/not-a-stupid-child/online-judge

oj_server

oj_server的本质就是一个小型网站。

主要采用MVC模式的编写。

  1. M : Model,通常是和数据交互的模块,比如,对题库进行增删改查(文件版,MySQL)。
  2. V: view, 通常是拿到数据之后,要进行构建网页,渲染网页内容,展示给用户的(浏览器)。
  3. C: control, 控制器,就是我们的核心业务逻辑。

model模块

对于model模块需要提供一个获取所有题目列表的函数,以及获取一个题目的函数,对于一个题目来说,需要有给用户的代码以及我们需要和用户提交代码拼接用来测试的代码,以及题目信息等很多的信息。所以要对题目进行描述。
在这里插入图片描述
所以我们可以提现建立好题库,如果是文件就提交建立好文件,如果数据库就提前建立好数据库和表结构,然后对于文件来说在找一个题是如果是线性查询太慢了,所以可以用unorder_map来维护一个题目序号和题目属性的一个结构,假设我们用题目序号来查找的,如果是别的就用别的建立这个结构,并且如果是文件我们需要再程序运行的时候就把所有的题目信息加载到我们的unordered_map中进行维护,数据库就不需要了因为索引的存在,查找单个也非常的快。

View模块

这个模块设计和前端的一些交互,需要和前端配合才能写正确,需要引入ctemplate的库,因为我们要用题目的信息去替换网页中的内容,所以就需要这个库。来将我们程序中的内容动态的显示到网页中。
这个库可以为我们维护一个key,value结构,然后在网页中通过{{key}}的方式来显示value的值。

在这里插入图片描述
我们需要一个获取全部界面的函数以及一个获取单个题的函数,所以我们就需要两个模板网页,一个应该将单个题目信息填充进去,一个用来把获取的全部题目的信息填进去,这两个模板网页因为博主是一个后端博主(博主也不太懂),就不讲这部分了,需要可以直接复制博主的代码,然后把模板网页和我们的数据一起渲染后得到新的网页返回给用户就好了。

Control模块

这个模块是我们的核心逻辑控制模块,当用户请求我们全部题目列表时我们需要给用户返回一个带有全部题目列表的页面,所以我们需要一个获取全部题目列表的函数,这个函数需要先通过Model木块获取全部的题目信息,然后把全部的题目信息给View的渲染全部题目列表网页的函数,得到模板网页和我们的数据一起渲染后的网页,返回给用户,当然用户也可能请求单张网页,和获取全部的题目列表的方式一样,先通过Model获取指定题目的信息,然后交给View的渲染单张网页的函数,然后把结果返回给用户就可以了。

这些都有了之后,就是用户提交了代码我们应该怎么办?
所以我们是还需要一个函数来对用户提交的代码进行处理的,用户通过网页的提交代码按钮,给我们提交上来的也是一个Json串,这个也是需要和前端服务沟通的,这个Json串中包含了用户提交的代码和用户的输入,我们拿到这个Json串之后,一定不能直接扔给编译服务,因为我们需要将用户的代码和我们测试用例的代码进行拼接,才能形成一份完整的代码,所以在收到Json串后,就是将Json串进行反序列化,然后构建新的Json串,这个新的Json串的内容和编译运行模块需要的Json串一样,在构建好给编译运行服务的Json串之后,就需要选择主机了,因为我们是负载均衡的选择主机,那么如何选择呢?

我们的编译服务可以部署在多台主机中,因此我们可以提前把部署编译运行服务的主机以配置文件的方式保存下来,因为在oj_server看来编译服务的主机会存在多台,所以就需要对主机进行管理,所以就需要对主机进行描述。
在这里插入图片描述
因为用户的个数一定是大于编译服务主机的个数的,所以就会存在多个用户同时让一个主机进行编译,因为一个用户让对应的主机编译,就需要增加该主机的负载,所以就涉及了多个用户同时访问修改同一个资源的问题了,所以每个用户都要一把锁来保证自身load的变化是原子的。

然后有了上面的内容后,接下来就是涉及一下负载均衡类了,这个类一定要将我们的主机给管理起来,因为它要选择负载最小的主机,在这个类实例化的时候,我们需要将所有主机的信息全部加载到程序中,本质就是读取配置文件,然后我们就有了所有主机的信息,我们需要对外提供一个选择主机的函数,这个函数可以将选择的主机的内容都返回出去,本质就是返回出去我们保存主机的信息的地址,然后通过load选择出来最小的主机,在这个模块中我们选择了hash的方式来保存主机的信息,我们把所有的主机用vector保存起来,然后对应主机的id就是数组的下标,然后在线主机和离线主机保存的就是这个id。
在这里插入图片描述

因为同时请求的用户会很多,我们也要保证对在线主机和离线主机的访问是安全的,不能说一个主机刚刚被离线,但是在在线列表中又访问到了,这是不安全的,所以我们还需要一把锁来保证我们负载均衡模块数据的安全性问题。然后我们有了只能选择主机的功能后,我们把重新构成的Json串就可以通过httplib把Json串发送给编译运行服务了,但是请求的这个主机可能已经离线了,所以我们死循环的选择主机并请求,如果请求失败了就认为主机离线了,然后把它从在线主机列表移到离线主机列表,然后接着选择,直到请求成功,或者全部服务都离线了才退出循环。

oj_server服务

这个服务主要是给用户提供路由功能的,根据用户请求的网页不同,给用户答应不同的网页内容。
用户请求全部的题目列表我们就调用control的获取全部题目列表网页的方法,然后在把得到的网页路由给用户,单个题目网页以及提交按钮的方式相同,只不过调用的函数不同,并且用户提交我们的到的是一个Json串,返回给用户的也是一个Json串。返回的Json串需要前端解析,呈现给用户。

如果我们的服务全部掉线了,我们可以对信号的方法进行重定义,在负载均衡模块加一个上线主机的函数,也就是把离线主机的内容全部给上线主机,然后就可以通过信号的方式,在确定主机全部重启后,让主机重新上线。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不是笨小孩i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值