Mastering Swoole PHP

讀書會#5

02/25

19:30~21:00

@17Live 大樓三樓 銀河灰會議室

OSI Model

TCP and UDP

TCP

  • Connection-oriented

  • Byte Stream

  • Ordered Data Delivery

  • Reliable

  • Handshake

  • Relatively Slow

UDP

  • Connectionless

  • Datagram

  • No Sequence 

  • Lossy

  • No Handshake

  • Relatively Faster

TCP and UDP

TCP Protocols

  • HTTP

  • FTP

  • SMTP

  • POP3

  • SSH

  • Redis

  • MySQL

  • Memcache

UDP Protocols

  • DHCP

  • DNS

  • NTP

  • VoIP

TCP and UDP

TCP and UDP

TCP and UDP

TCP and UDP

TCP and UDP

Sticky Packet in TCP

TCP and UDP

Sticky Packet in TCP

  • Nagle Algorithm

TCP and UDP

Sticky Packet in TCP

  • Buffer Size

TCP and UDP

Sticky Packet in TCP

  • Length and Delimiter

TCP and UDP

Sticky Packet in TCP

  • Length and Delimiter

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 138
...
Connection: close

<html>
  <head>
    <title>An Example Page</title>
  </head>
  <body>
    <p>Hello World, this is a very simple HTML document.</p>
  </body>
</html>

TCP and UDP

Sticky Packet in TCP

  • Length and Delimiter

+----------------+ 
| ABC\r\nDEF\r\n | 
+----------------+ 
+-----+-----+ 
| ABC | DEF | 
+-----+-----+ 

TCP and UDP

Redis Protocol

C: *2\r\n
C: $4\r\n
C: LLEN\r\n
C: $6\r\n
C: mylist\r\n
S: :48293\r\n

TCP and UDP

Redis Protocol

public function serialize(CommandInterface $command)
{
    $commandID = $command->getId();
    $arguments = $command->getArguments();

    $cmdlen = strlen($commandID);
    $reqlen = count($arguments) + 1;

    $buffer = "*{$reqlen}\r\n\${$cmdlen}\r\n{$commandID}\r\n";

    foreach ($arguments as $argument) {
        $arglen = strlen($argument);
        $buffer .= "\${$arglen}\r\n{$argument}\r\n";
    }

    return $buffer;
}

Concurrency and I/O Model

Concurrency and I/O Model

Parallel in PHP

<?php

use Amp\Parallel\Worker;
use Amp\Promise;

$urls = [
    'https://secure.php.net',
    'https://amphp.org',
    'https://github.com',
];

$promises = [];
foreach ($urls as $url) {
    $promises[$url] = Worker\enqueueCallable('file_get_contents', $url);
}

$responses = Promise\wait(Promise\all($promises));

foreach ($responses as $url => $response) {
    \printf("Read %d bytes from %s\n", \strlen($response), $url);
}
  • PHP Worker
  • PHP's Built-in Web Server

Concurrent I/O Models

Single Process and Blocking I/O

eg. PHP FPM

Concurrent I/O Models

Multiple Processes and Blocking I/O

eg. Java's Tomcat

Concurrent I/O Models

Multiple Threads and Blocking I/O

eg. Node JS

Concurrent I/O Models

Single Thread and Non-Blocking I/O

eg. Java Netty

Concurrent I/O Models

Reactor and Multiple Threads

Concurrent I/O Models

Java Netty

Concurrent I/O Models

Swoole

Concurrent I/O Models

Multiple Threads and Coroutines

Event Driven and Callbacks

React PHP

$loop = React\EventLoop\Factory::create();
$client = new React\HttpClient\Client($loop);

$request = $client->request('GET', 'https://github.com/');
$request->on('response', function ($response) {
    $response->on('data', function ($chunk) {
        echo $chunk;
    });
    $response->on('end', function() {
        echo 'DONE';
    });
});
$request->on('error', function (\Exception $e) {
    echo $e;
});
$request->end();
$loop->run();

Swoole

$http = new Swoole\Http\Server('127.0.0.1', 9501);

$http->on('start', function ($server) {
    echo "Swoole http server is started at http://127.0.0.1:9501\n";
});

$http->on('request', function ($request, $response) {
    $response->header('Content-Type', 'text/plain');
    $response->end('Hello World');
});

$http->start();

Event Driven and Callbacks

Callback Bindings in PHP

$server->on('request', function ($req, $resp) use ($foo) {
    echo "hello world";
});

Event Driven and Callbacks

Anonymous Function

Callback Bindings in PHP

class A
{
    static function test($req, $resp)
    {
        echo "hello world";
    }
}

$server->on('request', 'A::test');
$server->on('request', ['A', 'test]));

Event Driven and Callbacks

Static Function

Callback Bindings in PHP

function onRequest($req, $resp)
{
    echo "hello world";
}

$server->on('request', 'onRequest');

Event Driven and Callbacks

Function

Callback Bindings in PHP

class A
{
    function test($req, $resp)
    {
        echo "hello world";
    }
}

$object = new A();
$server->on('request', [$object, 'test']);

Event Driven and Callbacks

Object Function

Facts, Cost and Limit

Latency Numbers

Facts, Cost and Limit

Latency Numbers

Facts, Cost and Limit

Ulimit

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3900
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3900
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Facts, Cost and Limit

Error: Too many open files

2021/01/01 00:00:00 [alert] 7387#0: *6259768 socket() failed
(24: Too many open files) while connecting to upstream,
client: 123.123.123.123, server: www.example.com,
request: "GET [[/]] HTTP/1.1", upstream:
"fastcgi://127.0.0.1:9000", host: "www.example.com"
ulimit -n 50000

Discussion

Mstering Swoole PHP 讀書會#5

By Albert Chen

Mstering Swoole PHP 讀書會#5

  • 367