0

I have a Silverspripe Page with a sports Liveticker and a RestAPI for iOS and Android App. Every call I make that is Not in the static cache makes some System calls setting a filelock.

I have this function in my jsonapi Controller:

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;
        }
    }

When I call it even with ID=0 Silverstripe sets these Filelocks. When 200 Clients at the same time calling it my server goes down. 100% CPU usage with systemcalls like this:

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

It's files like _ss_environment.php ect. (probably every .php thats in use. So the Cliens are blocking each other with all these locks. How can I disable it? Is there some sort of global Variable to disable unneeded filelocks? Or do I have to change this in the core? Where can I find it?

1 Answers1

1

Serving for 200 concurrent users is quite a huge requirement in my opinion.

You are assuming that SilverStripe causes the file locks but I think you are hitting the max of what your server, service configuration and the used application stack can handle.

For example the the _ss_environment.php is just loaded with

include_once(SS_ENVIRONMENT_FILE);

So just basic php so the locks probably come from the operating/php system level.

In your case you'd need to figure out what is the maximum that the single web server can serve decently and start tweaking the values for php, the web server used and also on the operating system level as thats giving the files to php to work on ultimately:

I found this book once https://www.scalingphpbook.com/ has quite lot good details on getting the most out of a server.

Thought optimizing with the settings only goes so far so you'd probably think on scaling the nodes vertically or horizontally.

Difference between scaling horizontally and vertically for databases .

And make it add resources by load if possible to be more cost efficient on non high load times.

Olli Tyynelä
  • 586
  • 3
  • 14
  • 1
    It's worth mentioning that SilverStripe doesn't support scalable MySQL databases (read replicas) at the moment, unless you were to implement the fragmentation at the infrastructure level - [MySQL has made some moves](https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-replication-multi-master.html) in this area recently – scrowler Mar 21 '18 at 03:03