Open tiancheng91 opened 6 years ago
<?php $http = new swoole_http_server("127.0.0.1", 9501); // 自动设置全局变了, 兼容 $http->setGlobal(HTTP_GLOBAL_ALL); $http->set( [ 'worker_num' => 1, 'daemonize' => false, 'dispatch_mode' => 3, // 1:轮训, 3: 抢占 'discard_timeout_request' => true, // 丢弃已关闭的连接请求 'max_request' => 0, // 处理多少任务后退出worker,释放内存 'max_coro_num' => 300, // 协程数, 注意cli memory_limit ] ); $http->on('WorkerStart', function($server) { global $serv; $serv = $server; // $GLOBALS }); $http->on('request', function ($request, $response) { global $serv; //捕获异常 register_shutdown_function(function() use ($response) { $response->status(500); $response->end(); }); // 进入后先重制状态, 如全局变量, 实例状态等 // 一般不用协程或异步的话, 会完全阻塞, 相对的可以使用全局变量,无缝对接现有代码. // 优势: 不需要花时间重建opcache, 可以直接使用workerstart里预先初始化好的实例. 能大幅度减少执行时间. // 缺点: 进程数对应并发上限, 超出的请求会被阻塞. // 同步情况下, 建议设置 dispatch_mode = 3, discard_timeout_request => true // 同步情况下, 并发数超过wokers数时,建议抛弃超时请求, 要不队列积压会影响后续所有请求响应时间 // 超出负载时断开连接? 否则会一直等待中. $clientInfo = $serv->getClientInfo($request->fd); if (microtime(true) - $clientInfo['connect_time'] > 3) { $response->status(502); $response->end('502 error'); return; } // connect, recv触发协程切换 // $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); // Coroutine 可能和 xdebug库冲突, 注意协程下空间变量污染问题. 如 ob_start, ob_clean // 目前没什么好办法兼容, 数据库驱动如果为原生php的, 可以尝试替换 socket_connect/recv 为 swoole的版本. echo time(); sleep(10); // $request->setGlobal(); // ob_start(); // $response->output = ob_get_contents(); // ob_end_clean(); // $response->end(); $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); }); $http->start();
https://github.com/swooletw/laravel-swoole https://github.com/kcloze/slim-swoole
协程pdo兼容, https://github.com/swooletw/laravel-swoole/tree/feature/coroutine_feature/src/Coroutine 没特殊需求不建议使用co特性, 项目首先保证fpm正常运行情况下加swoole启动器做优化.