Teach you to use PHP Swoole-Tracker-second positioning PHP stuck problem

PHPer certainly received such complaints: small chrysanthemum has been transferred! How your website so card! When this happens we are stuck online business (blocking), most PHPer will be two of a smear, then think of the famous phrase: 性能瓶颈都在数据库Then put the pot training and preparation DBA, and quickly look slow sql, but this is very wrong approach, because there are too many factors that can lead to business stuck, stuck listed some common questions below.

1. infinite loop

The most common is to write an infinite loop Code

. 1 ? < PHP
 2  the while (. 1 ) {
 . 3     // do something 
. 4      IF ( $ for condition Condition ) {
 . 5          // exit the loop after the condition is satisfied 
. 6           BREAK ;
 . 7      }
 . 8 }

 

The code through $conditionthe control loop to exit, if not strict verification procedures, in some cases $conditionnever lead to true will request stuck.

2.sesstion_start function causes stuck

PHP's session lock wait (ps: many places called the session a deadlock, which do not meet the definition of a deadlock), which I believe most PHPer have encountered, PHP will default session information is stored in /tmp/sess_the following session file inside, call the session_start()function when will call flockthe system call to the session file locking, if the request is not the end of the previous session or manual release will lead to subsequent requests can not get a lock, stuck in session_start()this place. Here's an example of this kind of code, such as:

setInterval(function () {
    $ .Post ( "/ Ajax / doSomething", {}, function (Result) { // lS once Ajax 
         });
}, 1000)//1000ms == 1s

 

Js ajax request by the timing of the front at the back-end PHP interface ( /ajax/doSomething) to do some of the more time-consuming thing, people may write code granted that first request even if not finished processing, it will not affect the request for the second time, because there are a lot of FPM processes each request will be distributed to the process does not make sense, but does not know that the second request will get stuck in session_start().

3.flock function causes stuck

The most common scenario is to write the log, in the PHP code to ensure that each fwritecase is less than the contents of the log write 8k we can use atomic append an additional way to write the log, but can not guarantee less than 8k if we need to write the log before each file encryption file lock between the two logs are generated to avoid the situation interspersed, as follows:

? < PHP
 $ FP = the fopen ( "/home/guoxinhua/php.log", "A +" );
 IF ( Flock ( $ FP , LOCK_EX)) {   // to the log file lock
   //do something
    fwrite($fp, "the huge string\n");
    flock($fp, LOCK_UN);    // 释放锁定
}

 

If the lock is obtained A process for some problems blocking the process B will then stuck in the third row flockposition, unless A kill off the process, the system will automatically release the file locks

Note that there are many other types of locks even if the process is kill will not automatically be released.
This is 8k can be changed, and in glibc fwrite many details are not the same.   

4. The network client is not set timeout

MySQL, CURL, Swoole \ Client-peer client did not set the timeout may cause the process to block. Swoole \ Client when establishing a TCP connection connectmethod last parameter is the timeout, -1that is never time out, set the attention here is not just referring to this connectmethod, but behind all send, recvare never time out, in synchronous blocking programming model next, if at this time of the end machine downtime and other direct causes of the network is, then the performance of the business end is stuck state, all send, recvthe method will be blocked, as follows:

<?php
$cli = new Swoole\Client(SWOOLE_SOCK_TCP);
if ($cli->connect('127.0.0.1', 9501,-1)) {
      $cli->send("data");
      $cli->recv();
} else {
      echo "connect failed.";
}

 

5. Swoole lock coroutine

In Swoole coroutine mode, incorrect use can lead to lock all coroutine stuck a large area, the following code, by gocreate two coroutines method (the students do not understand the coroutine can be understood as creating two threads), the first coroutine lock after lock to get in co::sleepposition to make the cpu then began to execute the second coroutine, second coroutine will get stuck in a position to acquire a lock line 6, while the first and never coroutine It can not be restored to continue.

? < PHP
 $ Lock = new new Swoole \ Lock ();
 $ c = 2; // create two coroutines 
the while ( $ c - ) {
    Go ( function () use ( $ Lock ) { // create a coroutine 
        $ Lock -> Lock (); // get the lock 
        Co :: SLEEP (1); // give up the CPU 
        $ Lock -> UNLOCK (); / / release lock 
    });
}

 

How to find stuck

These are just cite a few examples, there are a variety of positions in the real business of stuck, encounter such problems experienced PHPer will use strace -pthe view command in the current PHP process which in the end blocking system call above to locate the problem, but this approach there are several issues:

  • Orientation is not clear
    example of this deadlock problem when strace can only see something like futex(0x7f4c8d567128, FUTEX_WAIT, 2, NULL)this information is not very intuitive, many people simply do not know what PHP code will trigger futexthe system call, as well as the previously mentioned session_startthat problem, a lot of people did not know there would be triggered flock, also said that it is difficult to target specific issues according to a system call.
  • -P do not know what process
    we start the online environment often dozens or even hundreds of PHP processes, stuck in some requests, some requests under normal circumstances, you in the end that strace -pwhich process it? Looks like the only chance.
  • Can not find the problem the cycle of death
    due to the straceprinciple of command is to track all system calls, if it is the first case mentioned earlier, that is, the cycle of death stuck, stracesimply can not get any useful information. At this point we can only use the gdbtool to get an infinite loop where specific current, specific practices are as follows: First: gdb attachback then a process id.
    Then:
    p (char *)executor_globals.current_execute_data.func.op_array.filename.valPrint PHP file currently being executed.
    p (char *)executor_globals.current_execute_data.func.op_array.function_name.valPrint the name of the function currently executing.
    p executor_globals.current_execute_data.opline.linenoPrint the number of lines currently being executed.
    Further call stack can get here not carried out.
    But the bottom too obvious, a lot of details to note, is not proficient in the PHP core is very difficult to find such a problem (ps: by .gdbinitcan slightly reduce the points of difficulty, but there are many other issues).

Use Swoole Tracker found stuck problem

In response to these problems, Swoole official out a solution Swoole Tracker stack tool supports both FPM and Swoole.
Very simple to use:

  • First click on the link above registered accounts.
  • Then install the swoole_trackerextension.
  • Finally landing back at 调试器=> 进程列表Click the 堆栈button to get the current card on which the figure:

 

 

 

end

In addition to the above problem stuck, there is a situation that calls slow down, such as the original system call 5ms, but due to network and other reasons, the call will return to 100ms, the performance of the business is slower and not stuck in there, this situation can not catch stack tool by positioning tracker problems, stuck because time is very short, very difficult to catch the call stack, then need Swoole tool chain is another tool 阻塞IO检测工具we'll tell you later.

Guess you like

Origin www.cnblogs.com/a609251438/p/11798948.html