criyle / go-judge

Sandbox Server in REST / gRPC API. Based on Linux container technologies.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

偶发性编译时间超限

winterant opened this issue · comments

大佬你好,
我们学校的oj使用了大佬开发的go-judge,目前遇到一个问题,想请教一下。这个问题只发生在服务器上,很难复现,遇到的概率可能不到10%。

网页端发送的编译请求如下:

{
    "cmd": [
        {
            "args": [
                "/bin/bash",
                "-c",
                "/usr/bin/g++ Main.cpp -std=c++20 -O2 -DONLINE_JUDGE -w -fmax-errors=1 -lm -o Main"
            ],
            "env": [
                "PATH=/usr/bin:/bin"
            ],
            "files": [
                {
                    "content": ""
                },
                {
                    "name": "stdout",
                    "max": 10240
                },
                {
                    "name": "stderr",
                    "max": 10240
                }
            ],
            "cpuLimit": 10000000000,
            "clockLimit": 20000000000,
            "memoryLimit": 536870912,
            "procLimit": 128,
            "copyIn": {
                "Main.cpp": {
                    "content": "#include<bits/stdc++.h>\nusing namespace std;\nint main()\n{\n\tint a,b;\n\tcin>>a>>b;\n\tcout<<a+b<<endl;\n}"
                }
            },
            "copyOut": [
                "stdout",
                "stderr"
            ],
            "copyOutCached": [
                "Main"
            ]
        }
    ]
}

给定的编译时间是10秒,有很小的概率会返回编译超时,瞬间返回结果,显然并没有达到10秒。

其它信息

  • 我们的实体服务器规格为CPU32核,内存64GB,系统Ubuntu 18.04(部署于256GB固态上),OJ采用docker-compose部署(文件挂载于500GB的机械硬盘上)。
  • OJ网页端启动了8个队列并行向go-jduge发送判题请求,也就是说同一时间最多有8个请求发给go-judge。
  • 在个人电脑上部署系统,无法复现这个问题,所以我猜想是否跟高并发有关?

感谢大佬百忙之中予以指教!

还有一个猜想:cpuLimit字段整数太大溢出了吗?网页端是php,int类型是64位,不会溢出。不知道http请求发出去之后有没有溢出?

所有参数都是无符号64位整数,理论上不会溢出的。cpu限制是实际使用量,比方说10线程运行一秒使用量就是10秒,现实世界过去1秒。
如果方便的话,提供一下程序版本和请求的返回值。可以用 -enable-debug 来输出日志。

ps 通常来说编译万能头都很需要计算。考虑到服务器主频通常偏低,也许可以考虑增加时间限制。

cpu限制是实际使用量,比方说10线程运行一秒使用量就是10秒,现实世界过去1秒。

我明白了,是这个原因造成的。
这个问题遇到的最多的情况是使用javac编译命令,测试了一下javac编译一次需要procLimit>=15才能成功,然而服务器是十年前老古董,cpu主频很低,总时间只给了10秒过于苛刻了。

感谢大佬答疑~

javac 我一般建议开 30s 的 limit 🤣