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