基于Docker的沙盒评测系统

docker系列文章:https://www.jianshu.com/nb/30096674

来源:
https://oi.men.ci/docker-sandbox-judger/
https://yq.aliyun.com/articles/65285

使用Docker的沙盒系统的优点

  • 隔离主机环境,保证安全性需求
  • 避免联网等操作
  • 有dockerode等易于实现的库
  • 无需限制系统调用

时间限制

使用setrlimit等函数,也可以直接设置监视线程,在时间到时直接结束进程。

资源限制

使用 -m 100m -cpuset 1 -cpushare 512这样的方法进行CPU和内存的限制。

微信公众号第三方配置及接口

微信官方给出的开发文档中Start Up部分:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1472017492_58YV5

具体实现可以参考:https://github.com/ThssSE/WeChatTicket/blob/master/wechat

下面也将用上述工程中的部分代码说明。

接口测试公众号

申请地址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

在上面设置URL、token、域名等信息后,即可开始进行测试。

其中token是自己随便写的,与服务器那边保持一致就行。

与微信交互的信息格式

后端与微信公众号交互时,使用的消息格式为XML格式,如下所示:

1
2
3
4
5
6
7
8
<xml>
<ToUserName><![CDATA[公众号/粉丝openid]]></ToUserName>
<FromUserName><![CDATA[粉丝openid/公众号]]></FromUserName>
<CreateTime>1460537339</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[具体内容]]></Content>
<MsgId>6272960105994287618</MsgId>
</xml>

如果使用图片等内容,需要使用其MediaId。此时MsgType为<![CDATA[image]]>,并且用Image标签包含<MediaId><![CDATA[gyci5oxxxxxxv3cOL]]></MediaId>的内容。

其中,MediaId对应的图片可以通过网址https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID下载。

自定义菜单

通过服务器向网站https://api.weixin.qq.com/cgi-bin/menu/create?access_token=XXXX进行POST操作来创建菜单,参数为类似如下格式的字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
postJson = """
{
"button":
[
{
"type": "click",
"name": "开发指引",
"key": "mpGuide"
},
{
"name": "公众平台",
"sub_button":
[
{
"type": "view",
"name": "更新公告",
"url": "http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1418702138&token=&lang=zh_CN"
},
{
"type": "view",
"name": "接口权限说明",
"url": "http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1418702138&token=&lang=zh_CN"
},
{
"type": "view",
"name": "返回码说明",
"url": "http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433747234&token=&lang=zh_CN"
}
]
},
{
"type": "media_id",
"name": "旅行",
"media_id": "z2zOokJvlzCXXNhSjF46gdx6rSghwX2xOD5GUV9nbX4"
}
]
}
"""

之后可以在后台接收POST数据,并且进行对应的处理。

代码实现

如无特殊说明,以下所指代码均在ThssSE/WeChatTicket/wechat下。

access token相关:

使用wrapper.py文件中的WeChatLib的类函数get_wechat_access_token,检查是否超时并且在必要时从https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxx&secret=xxx获取access token,通过类函数和类变量来进行access token的管理。

认证:

通过wrapper.pyWeChatLib类的check_signature函数实现,排序后哈希处理即可。

见get_wechat_menu与set_wechat_menu这两个函数

signature认证

WeChatView类中_check_signature函数

用户事件响应

do_dispatchparse_msg_xml函数,通过对微信发过来的POST事件进行解析、认证后,直接发送给对应的handler列表进行检查,让他们对这些数据进行对应的相应。

handlers.py文件中所写内容,check函数首先通过发送消息的类型与标识进行判断(对于文本内容直接检查文本数据是否符合要求,点击事件直接通过与自己在设置菜单时设置的event_key进行比对来确认),之后直接返回对应的数据并经过wrapper.py文件中do_dispatch函数,用HttpResponse进行XML格式封装,返回微信服务器。

持续集成实验总结

在这一次持续集成实验中,我们在学长们已经完成的前端和部分后端框架的基础上补充完成了微信抢票程序,我主要完成的是后端与微信公众号相关的接口部分(包括用户页面、公众号中菜单和回复操作的响应)。

这次实验由于时间比较紧急,比较仓促,但在整个过程中了解到了持续集成的开发方法,对微信公众号应用有了更为深刻的认识,同时也对git的使用更加熟练。

关于代码架构

在阅读原有的代码时,我感受到了学长们顶层设计的科学性,但是高封装性带来的就是在初步上手时的不适应。

同时,由于此次开发过程较为仓促,导致很多功能的实现仅仅是实现了对应的函数但是并未继续过多考虑与原有架构设计的相容性。而且由于顶层设计已经完成,并未在开发前在明确架构设计上花费较多时间,这也就使得不同成员开发的过程中会以不同的思考方式对原有架构进行修改,从而因为重复设计造成一些冗余的代码。这也更让我理解到架构设计的重要作用。

关于git&持续集成

本次实验使得我们对git的使用更加熟悉,特别是在merge conflict的时候更是通过搜索来获取了许多git常用指令。之前的开发过程中虽然也使用过git,但其作用往往只是保存代码,也没有涉及到比较大的conflict的情况。

git的使用的确是团队开发过程中所必不可少的,通过它可以使得我们及时了解到别人对代码修改的进展以及之前几次修改的情况,如果没有git的使用可能持续集成就无从谈起了。

在持续集成的开发过程中,每个人都在不断地向master分支进行pull request并且每一次都进行测试,同时可以设置在测试通过后直接部署。这种方式能够用不断地测试来让我们及时了解到代码的bug所在。

但是持续集成的优势是基于test的,在开发过程中因为test的编写有一些corner case没有覆盖到,就会导致开发过程中个别问题没有被及时发现。

在像我们这次任务一样的时间短任务量较大的情况,我觉得是非常适合采用持续集成的方法的。这样可以在加快开发进度的同时用足够的验证来保证代码的正确性与可用性。

关于微信公众平台相关接口

由于这次我的工作与微信公众平台的关联程度较高,因此查阅了一些相关资料,整理摘录一些自己认为比较重要可以帮助到别人的部分放在了https://www.jianshu.com/p/0cdc3f85afa3上。

关于MVC设计模式

在这次持续集成实验中,我对于学长们对于整体代码架构的设计有了很深的印象,因此我在网上了解了一些关于MVC设计模式的内容,并且摘录到了https://www.jianshu.com/p/d90a5942e187。

关于测试

在本次实验中我深刻感受到了对代码进行测试的必要性,因此了解了更多的代码测试相关的内容,放在了文集https://www.jianshu.com/nb/30319209内。