Why does PHP sometimes hang on session_start ()

NB This is not a PHP session_start () trick that causes HTTP requests to hang (and other similar questions asked on SO) since my hang is random and not constant.

Using Ubuntu 12.04, Magento , PHP-FPM (5.4) and the default PHP session handler (with files on ext4).

By the way, (once per month) all PHP processes hang on session_start() (according to fpm-slow.log):

 [24-Sep-2014 11:03:04] [pool www] pid 24259 script_filename = /data/web/public/index.php [0x00007f00b4ec6480] session_start() /data/web/public/includes/src/__default.php:7687 [0x00007f00b4ec6130] start() /data/web/public/includes/src/__default.php:7730 [0x00007f00b4ec5fb8] init() /data/web/public/includes/src/__default.php:8086 [0x00007f00b4ec5e30] init() /data/web/public/includes/src/__default.php:33902 [0x00007f00b4ec5bd0] __construct() /data/web/public/includes/src/__default.php:23841 [0x00007f00b4ec5ae8] getModelInstance() /data/web/public/app/Mage.php:463 [0x00007f00b4ec59c8] getModel() /data/web/public/app/Mage.php:477 [0x00007f00b4ec49a0] getSingleton() /data/web/public/includes/src/__default.php:14044 [0x00007f00b4ec4848] preDispatch() /data/web/public/includes/src/Mage_Adminhtml_Controller_Action.php:160 [0x00007f00b4ec3b00] preDispatch() /data/web/public/includes/src/__default.php:13958 [0x00007f00b4ec26e0] dispatch() /data/web/public/includes/src/__default.php:18331 [0x00007f00b4ec20c0] match() /data/web/public/includes/src/__default.php:17865 [0x00007f00b4ec1a98] dispatch() /data/web/public/includes/src/__default.php:20465 [0x00007f00b4ec1908] run() /data/web/public/app/Mage.php:684 [0x00007f00b4ec17f8] run() /data/web/public/index.php:87 

Lsof says:

 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME php5-fpm 24259 app 10uW REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 php5-fpm 24262 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 php5-fpm 24351 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 php5-fpm 24357 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 php5-fpm 24358 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 php5-fpm 25563 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 php5-fpm 25564 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6 

According to strace, all of these processes are waiting for the flock (LOCK_EX) , even one who has the W flag in the lsof output above.

CPU usage for this incident is around 0.

So why does the first session_start hang, even though it seems to have acquired a write lock on the session file? How could I debug this further?

Here's a discussion called " race condition with ajax and php sessions ." In fact, the requests that cause the problem above are persistent AJAX calls. However, this article states that:

If you used the built-in PHP default session processing (which uses files), you will never run into a problem.

So now I'm at a loss where to look further.

+7
source share
7 answers

I believe that it is better to store sessions on a local disk rather than in a database.

Create a directory called "sessions" in the root directory, and then write down all your sessions by putting the following code at the top of the scripts right before the call to "session_start ()"

 $session_path = $_SERVER['DOCUMENT_ROOT']; //this session path assumes you are not using a subdomain ini_set('session.save_path', $session_path.'/sessions/'); 

Downloading from a file is faster than downloading from a database. And php controls it all, so I choose speed.

+1
source

Something unknown blocks the first script, and it blocks the rest.

PHP keeps the session file open for writing until the script completes. This means that if the script is stuck or caught up with something slow, all other session-specific requests will be blocked until they end.

Two best practices - do not start the session until you need it, and explicitly end the session_write_close () session when you change it, especially before you make something slow or potentially erroneous.

Then you will have only one stuck process, not a blocked user.

+1
source

In your Ajax calls, I assume that you have session_start in this file, and somewhere in your / tmp directory on your ubuntu php its session is saved. To solve your problem, you need to run load testing for these scenarios, it can also be db, which can be a factor in which you cannot see with the naked eye.

Try something like this: http://smartbear.com/products/qa-tools/load-testing-tool/ajax-load-testing/ as a trial version, maybe you can figure out the essence of the problem. You also need to delve into the sessions, including those individual files that use ajax calls.

You must configure some type of performance testing for these backend calls that you can run when a problem occurs. The layers are PHP, PHP-FPM, Magento, Im, assuming MySQL, Ubuntu, network connectivity and Apache?

0
source

When you have a script import that takes a long time, the browser is blocked and you can no longer access the website. this is because the request reads and locks the session file to prevent corruption.

you can either - use another session handler with session_set_save_handler () - use session_write_close () in the import script, as soon as you no longer need the session (the best moment before lasting during the part), you can session_start whenever you want and how many times you like if your import script requires changing session variables.

http://php.net/manual/en/function.session-start.php

0
source

I would advise checking the session table on magento ... since it stores sessions in the mysql table, you might have a problem with your db ...

0
source

It is good practice to install memecached for php and then just set these values:

 session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211″ 
0
source

I just read on different platforms because I am facing the same problem. I read on several pages that the process of cleaning up session files starts when you call "session_start ()". You can control how often and how the garbage collector (gc) cleans in ini php directives

0
source

Source: https://habr.com/ru/post/975773/


All Articles