A
A
antobra2021-12-23 21:04:13
PHP
antobra, 2021-12-23 21:04:13

Data transfer degradation through php stream_socket_server and non-blocking mode?

Prompt the decision of two questions, concerning PHP and ports.

Background for understanding :

The simplest client-server code communicating through the port on 127.0.0.1 (code below in paragraph 2). It works, but with two problems, which are described below:

1. The same code works differently on Debian 11 and MacOs Big Sur, namely...

It so happened that I write and test code on macOS. The script works perfectly and there are no problems. But as soon as I upload to Debian, on which the code will work in the future, something interesting appears: Each request reduces the port bandwidth. Here is an example of a self-written benchmark, on which the results of 1000 requests through the port. You can notice that after each test of 1000 requests, the processing time increases and the number of skipped requests degrades. That is, by the 5th test, instead of 1 second, it takes almost 9 seconds. And the execution time for one call to the port from 0.001 seconds becomes 0.008. I must explain right away: Nothing resource-intensive happens on the server, the server simply returns a string like hello world (see the code below in paragraph 2).

Test #1:
Queries: 1000
One query (sec): 0.001090964
Requests Per Sec: 916
Time: 1.090964

Test #2:
Queries: 1000
One query (sec): 0.002816856
Requests Per Sec: 355.00572269225
Time: 2.816856

Test #3:
Queries: 1000
One query (sec): 0.004799131
Requests Per Sec: 208.37105717681
Time: 4.799131

Test #4:
Queries: 1000
One query (sec): 0.006820563 Requests
Per Sec: 146.61546268248
Time: 6.820563

Test # 50
Queries: 10
0.00859813
Requests Per Sec: 116.30435920369
Time:8.59813


In this case, the same code on MacOs:

Test #1
Queries: 1000
One query (sec): 0.000561929
Requests Per Sec: 1779.5842535267
Time: 0.561929

Test #3 Queries
: 1000 One
query (sec): 0.000506018 Requests
Per Sec: 1976.2142848673
Time: 0.506018 One query (sec): 0.000501011 Requests Per Sec: 1995.9641604675 Time : 0.501011 Test #4 Queries: 1000




You can see that on the Mac, the results are stable and stay at a certain level.

Obviously it's the OS. But what exactly? Tell me, if anyone knows

2. Non-blocking mode (and again the story with the OS)

The second problem is that the non-blocking mode does not work. That is: the server is started, several tens of clients are started. And by the way clients execute requests, it is noticeable that they are still waiting for neighboring clients to complete the connection. Please tell me how to fix the code so that the situation is resolved. But that's not all: The following code works in non-blocking mode on MacOs without problems, but does not work in non-blocking mode on Debian.

Important: the lines with checks of the results of the execution of functions have been removed in the code to improve readability. They do not affect the general logic in any way, but they significantly complicate reading.


And here is the Server code itself:

$server = stream_socket_server ( 'tcp://127.0.0.1:30000', $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN );

stream_set_blocking ( $server, false );

while ( true ) {

  $connections = [];

  if ( $c = @stream_socket_accept ( $server, -1, $peer ) ) {
  
    $connections[ $peer ] = $c; 
    
    $read = $connections;

    if ( stream_select ( $read, $write, $except, 5 ) ) {

        foreach ( $read as $connection ) {
            
            $peer = stream_socket_get_name ( $connection, true );
            echo "\nNew message. Peer: " . $peer;

            $stream_socket_recvfrom = stream_socket_recvfrom ( $connection, 8192 );

            echo "\nIncoming message: " . $stream_socket_recvfrom;

            $response = "Hello world";

            echo "\nResponse: " . $response;

      fwrite ( $connection, $response );
          
      stream_socket_shutdown( $connection, STREAM_SHUT_RDWR );
      fclose ( $connection );
      unset ( $connection );

        }

    }

  }

}

stream_socket_shutdown( $server, STREAM_SHUT_RDWR );
fclose ( $server );
unset ( $server );


client:

$client = @stream_socket_client ( 'tcp://127.0.0.1:30000', $errno, $errstr, 30, STREAM_CLIENT_CONNECT );

$message = "Hiii";

fwrite ( $client, $message );

$stream_socket_recvfrom = stream_socket_recvfrom ( $client, 8192 );
echo "\n" . $stream_socket_recvfrom;

stream_socket_shutdown( $client, STREAM_SHUT_RDWR );
fclose ( $client );
unset ( $client );


In all cases, PHP 8.1 is installed, the code is run through the console, the default settings (in both cases). To be honest, I broke my head. I even shoveled React PHP, but did not notice any features.

I will be glad to all opinions. Thanks

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
antobra, 2021-12-31
@antobra

Solution:
1. Make sure PHP code is correct
2. Set ulimit -u, ulimit -n
3. Set sysctl for highload
4. Reboot

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question