silverstripe 3.x fcntl导致性能问题

时间:2018-03-19 19:55:53

标签: performance silverstripe fcntl

我有一个Silverspripe页面,其中包含体育Liveticker和适用于iOS和Android App的RestAPI。 我做的每个调用都不在静态缓存中,这使得一些系统调用设置了一个文件锁。

我的jsonapi控制器中有这个功能:

function image(){
        if($this->request->param('ID')){
            $id = $this->request->param('ID');
            if($id > 0){
                $image = Image::get()->distinct(false)->byID($id);
                if(is_object($image) && $image->exists()){
                    $filetype = $image->getExtension();
                    $width = $this->getRequest()->getVar("width");
                    $height = $this->getRequest()->getVar("height");
                    if(isset($width) && isset($height)){
                        $url = $image->croppedImage($width,$height)->URL;
                    } elseif(isset($width)){
                        if($width == 0){
                            $url = $image->URL;
                        } else{
                            $url = $image->setWidth($width)->URL;
                            //Debug::log("setWidth URL: ".$url);
                        }
                    } else{
                        $url = $image->setWidth(1600)->URL;
                    }
                    header("Content-type: image/{$filetype}");
                    header("Cache-Control: public, max-age=2678400");
                    header('Content-Length: ' . filesize(Director::baseFolder().$url));
                    readfile(Director::baseFolder().$url);
                    die();
                }
            }
            return null;
        } else{
            return null;
        }
    }

当我用ID = 0调用它时,Silverstripe会设置这些Filelocks。当200个客户端同时调用它时,我的服务器出现故障。系统调用的100%CPU使用率如下:

fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl(22, F_SETLKW, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0

它的文件如_ss_environment.php等。 (可能每个.php都在使用中。 所以Cliens用所有这些锁相互阻挡。我该如何禁用它?是否有某种全局变量来禁用不需要的文件锁? 或者我必须在核心中改变这一点?我在哪里可以找到它?

1 个答案:

答案 0 :(得分:1)

在我看来,为200个并发用户提供服务是一个非常大的要求。

您假设SilverStripe导致文件锁定,但我认为您正在达到服务器,服务配置和使用的应用程序堆栈可以处理的最大值。

例如,_ss_environment.php刚加载

include_once(SS_ENVIRONMENT_FILE);

所以只是基本的php所以锁可能来自操作/ php系统级别。

在您的情况下,您需要弄清楚单个Web服务器可以正常服务的最大值,并开始调整php,所使用的Web服务器以及操作系统级别的值,因为这样可以提供文件php最终工作:

我发现这本书https://www.scalingphpbook.com/有很多关于充分利用服务器的细节。

只考虑使用设置进行优化,所以您可能会想到垂直或水平缩放节点。

Difference between scaling horizontally and vertically for databases

如果可能的话,通过加载来增加资源,以便在非高负载时间更具成本效益。