session_start seems to be very slow (but only sometimes) - php

For some odd reason, just today our server decided to be very slow during the starting of sessions. For every session_start, the server either times out after 30 seconds, or it'll take about 20 seconds for it to start the session. This is very weird, seeing as it hasn't done this for a very long time (the last time our server did this was about 7 months ago). I've tried to change the session to run through a database instead, and that works fine, however, as our current website is built, it'd take days to go on every page and change the loading of sessions to include a new session handler. Therefore my question remains:
Why is it so slow, and why only sometimes?
We run on a dedicated hetzner server with 24GB's of ram, and a CPU fast enough to just run a simple webserver (a Xeon, I believe, but I'm not sure). We run debian on the server with an apache+fastcgi+php5 setup.
The server doesn't report much load, neither through server-status as well as the top command. Vnstat reports no problem whatsoever with our network link (again, that wouldn't result in a slow local session handling). IOtop reports no problem with processes taking over the entire harddrive. Writing to the tmp folder where the session files are located works fast if done through vim.
Again, to make this clear, my main concern here isn't whether or not we should switch to a DB or a memory-cached version of the sessions, it's simply to ask why this happens, because everything I take a look at seems to be working fine, except for the PHP itself.
EDIT:
The maximum file in our PHP tmp directory is 2.9 MB, so nothing that should make an impact, I believe.
UPDATE: I did never figure out what was wrong and/or how to fix it, but the problem disappeared after we switched over to memcached/db sessions.

Have you tried session_write_close(); ?
This will disable write-ability in session variables but you can still read data from them. And later when you need to write a session variable, reopen it.
I have also suffered from this problem but this thing worked like a charm. This is what i do:
session_start(); //starts the session
$_SESSION['user']="Me";
session_write_close(); // close write capability
echo $_SESSION['user']; // you can still access it

I had the same problem: suddenly the server took 30 seconds to execute a request. I noticed it was because of session_start(). The first request was fast, but each next request took some 30 sec to be executed.
I found that the session file in c:\wamp\tmp was locked by the first request for some 30 sec. During this time the second request was waiting for the file to be unlocked.
I found out it had something to do with rewrite_mod and .htaccess. I disabled rewrite_mod and commented out every line in .htaccess and it works again like a charm. I don't know why this happend because I don't remember change any settings or conf on wamp.

I ran into this problem too. It was answered here:
Problem with function session_start() (works slowly)
Sessions are locked by PHP while one script is executing, so if scripts are stacked under the same session, they can cause these surprisingly long delays.

Each session is stored by apache as a text file.
When session start is use to resume an existing session (via cookie identifier for example) maybe a big session file (a Session with a lot of content inside) can be slow to be started?
If this is the case probably you application is putting to much data into sessions.

Please check if you have correct memcache settings e.g. in /etc/php.d/memcached.ini

I know this is an old question but I've just fixed this issue on my server. All I did was turn on the bypass cache for the domains in the cache manager in the cpanel.
My sessions were taking ages to start and close now they are instant.

Sessions also may start slow if you put many data in it. For example 50MB of data in session in docker image may result in 3 seconds of session start time.

Related

PHP session expires while in use

Recently my webhost changed the PHP configuration. The only complaint I have is that sessions expire while in use.
Generally, I just write once to the session, but read many times, so I thought this may be because the filemtime wasn't changing, so every time I read, I also write by incrementing a counter. Still nothing, after 24 minutes, whether the session is being used or not, it gets cleared.
Any ideas on how to fix this?
PHP constantly reads and writes the session data file when you start a session and end the script (or call session_write_close()), so the file mtime should change. There is no need to change the atime option of the filesystem.
But things can easily go wrong beyond that, including having strange cronjob scripts running that delete session files. Without you complaining at the service desk, they will never fix it.

PHP script stops running after some time run by browser

I have made a PHP script which probably would take about 3 hours to complete. I run it from browser and after about 45minutes it stops doing anything. I know this since its polling certain web addresses and then saves some data to database. So it basically stops putting any data to database which lead me to conclusion that it has stopped. It still shows in browser like it would be loading the page though but its neverending.
There arent any errors so it probably is some kind of timeout... But where it occurs is mystery or how can I prevent it from happening. In my case I cant use the CLI, I must user browser client to initiate the script.
I have tried to put
set_time_limit(0);
But it had no apparent effect. Any suggestions what could cause the timeout and a fix for it?
Try this:
set_time_limit(0);
ignore_user_abort(true);
ini_set('max_execution_time', 0);
Most webhosts kill processes that run for a certain length of time. This is intended as a failsafe against infinite loops.
Ask your host about this and see if there's any way it can be disabled for this particular script of yours. In some cases, the killer doesn't apply to Cron tasks, or processes run by SSH. However, this varies from host to host.
Might be the browser that's timing out, not sure if browsers do that or not, but then I've also never had a page require so much time.
Suggestion: I'm assuming you are running a loop. Load a page then run each iteration of the loop in an ajax call to another page, not firing the next iteration until the previous one returns.
There's a setting in PHP to kill processes after sometime. This is especially important for shared servers (you do not want that one process slows up the whole server).
You need to ask your host if you can make modifications to php.ini (through .htaccess). In particular the max_execution_time setting.
If you are using session, then you would need to look at 'session.cookie_lifetime' and not set_time_limit. If you are using an array, the array size might also fill up.
Without more info on how your script handles the task, it would be difficult to identify.

Do PHP timeouts stop people on the same network loading pages?

If I have a PHP page that is doing a task that takes a long time, and I try to load another page from the same site at the same time, that page won't load until the first page has timed out. For instance if my timeout was set to 60 seconds, then I wouldn't be able to load any other page until 60 seconds after the page that was taking a long time to load/timeout. As far as I know this is expected behaviour.
What I am trying to figure out is whether an erroneous/long loading PHP script that creates the above situation would also affect other people on the same network. I personally thought it was a browser issues (i.e. if I loaded http://somesite.com/myscript.php in chrome and it start working it's magic in the background, I couldn't then load http://somesite.com/myscript2.php until that had timed out, but I could load that page in Firefox). However, I've heard contradictory statements, saying that the timeout would happen to everyone on the same network (IP address?).
My script works on some data imported from sage and takes quite a long time to run - sometiems it can timeout before it finishes (i.e. if the sage import crashes over the weeked), so I run it again and it picks up where it left off. I am worried that other staff in the office will not be able to access the site while this is running.
The problem you have here is actually related to the fact that (I'm guessing) you are using sessions. This may be a bit of a stretch, but it would account for exactly what you describe.
This is not in fact "expected behaviour" unless your web server is set up to run a single process with a single thread, which I highly doubt. This would create a situation where the web server is only able to handle a single request at any one time, and this would affect everybody on the network. This is exactly why your web server probably won't be set up like this - in fact I suspect you will find it is impossible to configure your server like this, as it would make the server somewhat useless. And before some smart alec chimes in with "what about Node.js?" - that is a special case, as I am sure you are already well aware.
When a PHP script has a session open, it has an exclusive lock on the file in which the session data is stored. This means that any subsequent request will block at the call to session_start() while PHP tries to acquire that exclusive lock on the session data file - which it can't, because your previous request still has one. As soon as your previous request finishes, it releases it's lock on the file and the next request is able to complete. Since sessions are per-machine (in fact per-browsing session, as the name suggests, which is why it works in a different browser) this will not affect other users of your network, but leaving your site set up so that this is an issue even just for you is bad practice and easily avoidable.
The solution to this is to call session_write_close() as soon as you have finished with the session data in a given script. This causes the script to close the session file and release it's lock. You should try and either finish with the session data before you start the long running process, or not call session_start() until after it has completed.
In theory you can call session_write_close() and then call session_start() again later in the script, but I have found that PHP sometimes exhibits buggy behaviour in this respect (I think this is cookie related, but don't quote me on that). Obviously, pay attention to the fact the setting cookies modifies the headers, so you have to call session_start() before you output any data or enable output buffering.
For example, consider this script:
<?php
session_start();
if (!isset($_SESSION['someval'])) {
$_SESSION['someval'] = 1;
} else {
$_SESSION['someval']++;
}
echo "someval is {$_SESSION['someval']}";
sleep(10);
With the above script, you will have to wait 10 seconds before you are able to make a second request. However, if you add a call to session_write_close() after the echo line, you will be able to make another request before the previous request has completed.
Hmm... I did not check but I think that each request to the webserver is handled in a thread of its own. Thereby a different request should not be blocked. Just try :-) Use a different browser and access your page while the big script is running!
Err.. I just see that this worked for you :-) And it should for others, too.

Where to store a system flag?

This may seem a silly question, but having been pondering it for a few days, i've only come up with one answer, so I thought i'd throw it open and see what other people think.
I have a PHP script which runs as a CRON job, and checks that our CDN is up and running. If it is, it needs to set a flag to show 'true', if not to show 'false'. The main PHP webpages then need to check this flag everytime a user visits the site, and set the CDN URL variable appropriately.
The query is where do we store this flag? We could put it in a database, but then the database would get 'hit' every page load. Also, as we're using Memcache it could result in a delay to it being updated (although there are ways around that, obviously).
My next thought was to save it into a simple text file on the server. But a) we have load-balanced servers, and although we could run the same CRON job on each server, that seems inefficient, and b) opening and reading a text file could, i thought, slow the page load down, as its involving disk activity everytime - that isn't good when the system is delivering 3 million web pages a week!
The ideal would be PHP system variable that retains its value between pages - but of course, that doesn't exist! Its not the kind of information that should be stored as a cookie on the users machine either.
Does any one have any thoughts? All comments welcome!
If you are already using Memcache, then why do you need the CronJob at all?
Put the check for the CDN into your regular application code. Cache the result in Memcache with a lifetime of what your Cron Interval is right now. If the cache is stale, do the full checking on the CDN, otherwise return the cached result.
If you want to keep the CRON job and are concerned about Disk I/O, consider using a RAM disk or Semaphores or Shared Memory to store the results. But it seems kinda pointless when you are already using memcache.
Do you already use a database connection?
If so, use that; you can fit it into your existing replication mechanism pretty easily, I'm sure.
If not, then whatever you do here is going to add overhead, be it reading a text file on disk or reading from a database where you weren't before.

Does apache / php blocks a single file to be processed from the same client concurrently?

I have everything setup and running with KalturaCE & Drupak and the server (Ubuntu 8.02+Apache2+PHP5+MySql) is working fine.
The issue here I am having is unclassified.
When I play two videos together from my site, the second video which I played later doesn't start until the first completes its buffering. I did some HTTP watch and came to know that,
both of the entries request the file with the URL as follows,
/kalturace/p/1/sp/100/flvclipper/entry_id/xxxxxx/flavor/1/version/100000
so the first video which I played receives a 302 redirect response to the URL as follows,
/kalturace/p/1/sp/100/flvclipper/entry_id/xxxxxxx/flavor/1/version/100000/a.flv?novar=0
and starts buffering and playing. While the second video which I started later just wait for a response till the first video end its buffering and then the second video receives its 302 redirect and start buffering
My question is, why can't both videos buffer concurrently? and Obviously this is what I require.
Your help is highly anticipated and much welcome.
PHP file-based sessions will lock the session file while a request is active. If you intend to use parallel requests like this, you'll have to make sure each script closes the session as soon as possible (ie: after writing out any changes) with session_write_close() to keep the lock time to a minimum.
I found the solution to my problem and it was surely the Marc at first place suggested but it was some problem with mysql timeout as well.
So putting session_write_close() in both the files at right places solved my problem.
For a complete overview please visit the suggested thread at http://www.kaltura.org/videos-not-playing-simultaneously-0
I posted several suggestions at http://drupal.org/node/1002144 for the same question, this is one of them:
In Apache space, a possible cause might be MaxClients (or, the capacity of your Apache server to respond to multiple requests). If that apache setting or server capacity is low, then the server may be dropping your connections into its backlog until the first connection is completed. You can test this using regular large files which take some time to download on the server - that will establish whether it's KalturaCE or Apache which is causing the issue. To see this you'd either need a site which is already sitting at max for MaxClients (ie, not an unused dev site), or a very low MaxClients setting (like, 1!).
Another suggestion posted at http://drupal.org/node/1002144 for the same question -
It's possible that this behaviour might be due to a mysql query lock. If KalturaCE's SQL was locking a table until the first request is completed (I have no reason to believe this is the case, just floating possible causes), then a second request might hang like this.
I'm not familiar enough with CE to suggest that this is the case, but you could easily debug using mtop on the server during the request to see if this is what's actually happening.

Categories