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();
							 |