132 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
<?php
 | 
						|
include '../vendor/autoload.php';
 | 
						|
 | 
						|
use Smf\ConnectionPool\ConnectionPool;
 | 
						|
use Smf\ConnectionPool\ConnectionPoolTrait;
 | 
						|
use Smf\ConnectionPool\Connectors\CoroutineMySQLConnector;
 | 
						|
use Smf\ConnectionPool\Connectors\PhpRedisConnector;
 | 
						|
use Swoole\Coroutine\MySQL;
 | 
						|
use Swoole\Http\Request;
 | 
						|
use Swoole\Http\Response;
 | 
						|
use Swoole\Http\Server;
 | 
						|
 | 
						|
class HttpServer
 | 
						|
{
 | 
						|
    use ConnectionPoolTrait;
 | 
						|
 | 
						|
    protected $swoole;
 | 
						|
 | 
						|
    public function __construct(string $host, int $port)
 | 
						|
    {
 | 
						|
        $this->swoole = new Server($host, $port);
 | 
						|
 | 
						|
        $this->setDefault();
 | 
						|
        $this->bindWorkerEvents();
 | 
						|
        $this->bindHttpEvent();
 | 
						|
    }
 | 
						|
 | 
						|
    protected function setDefault()
 | 
						|
    {
 | 
						|
        $this->swoole->set([
 | 
						|
            'daemonize'             => false,
 | 
						|
            'dispatch_mode'         => 1,
 | 
						|
            'max_request'           => 8000,
 | 
						|
            'open_tcp_nodelay'      => true,
 | 
						|
            'reload_async'          => true,
 | 
						|
            'max_wait_time'         => 60,
 | 
						|
            'enable_reuse_port'     => true,
 | 
						|
            'enable_coroutine'      => true,
 | 
						|
            'http_compression'      => false,
 | 
						|
            'enable_static_handler' => false,
 | 
						|
            'buffer_output_size'    => 4 * 1024 * 1024,
 | 
						|
            'worker_num'            => 4, // Each worker holds a connection pool
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function bindHttpEvent()
 | 
						|
    {
 | 
						|
        $this->swoole->on('Request', function (Request $request, Response $response) {
 | 
						|
            $pool1 = $this->getConnectionPool('mysql');
 | 
						|
            /**@var MySQL $mysql */
 | 
						|
            $mysql = $pool1->borrow();
 | 
						|
            $status = $mysql->query('SHOW STATUS LIKE "Threads_connected"');
 | 
						|
            // Return the connection to pool as soon as possible
 | 
						|
            $pool1->return($mysql);
 | 
						|
 | 
						|
 | 
						|
            $pool2 = $this->getConnectionPool('redis');
 | 
						|
            /**@var \Redis $redis */
 | 
						|
            $redis = $pool2->borrow();
 | 
						|
            $clients = $redis->info('Clients');
 | 
						|
            // Return the connection to pool as soon as possible
 | 
						|
            $pool2->return($redis);
 | 
						|
 | 
						|
            $json = [
 | 
						|
                'status'  => $status,
 | 
						|
                'clients' => $clients,
 | 
						|
            ];
 | 
						|
            // Other logic
 | 
						|
            // ...
 | 
						|
            $response->header('Content-Type', 'application/json');
 | 
						|
            $response->end(json_encode($json));
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    protected function bindWorkerEvents()
 | 
						|
    {
 | 
						|
        $createPools = function () {
 | 
						|
            // All MySQL connections: [4 workers * 2 = 8, 4 workers * 10 = 40]
 | 
						|
            $pool1 = new ConnectionPool(
 | 
						|
                [
 | 
						|
                    'minActive' => 2,
 | 
						|
                    'maxActive' => 10,
 | 
						|
                ],
 | 
						|
                new CoroutineMySQLConnector,
 | 
						|
                [
 | 
						|
                    'host'        => '127.0.0.1',
 | 
						|
                    'port'        => '3306',
 | 
						|
                    'user'        => 'root',
 | 
						|
                    'password'    => 'xy123456',
 | 
						|
                    'database'    => 'mysql',
 | 
						|
                    'timeout'     => 10,
 | 
						|
                    'charset'     => 'utf8mb4',
 | 
						|
                    'strict_type' => true,
 | 
						|
                    'fetch_mode'  => true,
 | 
						|
                ]);
 | 
						|
            $pool1->init();
 | 
						|
            $this->addConnectionPool('mysql', $pool1);
 | 
						|
 | 
						|
            // All Redis connections: [4 workers * 5 = 20, 4 workers * 20 = 80]
 | 
						|
            $pool2 = new ConnectionPool(
 | 
						|
                [
 | 
						|
                    'minActive' => 5,
 | 
						|
                    'maxActive' => 20,
 | 
						|
                ],
 | 
						|
                new PhpRedisConnector,
 | 
						|
                [
 | 
						|
                    'host'     => '127.0.0.1',
 | 
						|
                    'port'     => '6379',
 | 
						|
                    'database' => 0,
 | 
						|
                    'password' => null,
 | 
						|
                ]);
 | 
						|
            $pool2->init();
 | 
						|
            $this->addConnectionPool('redis', $pool2);
 | 
						|
        };
 | 
						|
        $closePools = function () {
 | 
						|
            $this->closeConnectionPools();
 | 
						|
        };
 | 
						|
        $this->swoole->on('WorkerStart', $createPools);
 | 
						|
        $this->swoole->on('WorkerStop', $closePools);
 | 
						|
        $this->swoole->on('WorkerError', $closePools);
 | 
						|
    }
 | 
						|
 | 
						|
    public function start()
 | 
						|
    {
 | 
						|
        $this->swoole->start();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// Enable coroutine for PhpRedis
 | 
						|
Swoole\Runtime::enableCoroutine();
 | 
						|
$server = new HttpServer('0.0.0.0', 5200);
 | 
						|
$server->start(); |