Open guanhui07 opened 1 year ago
项目地址 https://github.com/joanhey/AdapterMan
看源码原理: 第一、禁止 php 自带函数的同时编写新的函数。 第二、提供新的启动入口使用workerman,同时把框架的核心加载代码,稍作修 改。这样就完美的接替了 php-fpm 。代码常驻内存,性 能提升还是肉眼可见的。当然这个里面的替换思路还是很有意思的。 第三、装上 event扩展 ,性能提升一个量级 , I/O 通知机制有效地安排基于 I/O、时间和信号的事件, epoll linux内核支持 io多路复用
workerman
event
epoll
https://pecl.php.net/package/event event扩展安装 此处忽略
php.ini 通过 disable_functions 禁用一些函数
disable_functions =header,header_remove,http_response_code, setcookie,session_create_id,session_id,session_name, session_save_path,session_status,session_start, session_write_close,session_regenerate_id,set_time_limit
start.php 启动文件
start.php
<?php require_once __DIR__ . '/vendor/autoload.php'; use Adapterman\Adapterman; use Workerman\Worker; Adapterman::init(); $http_worker = new Worker('http://0.0.0.0:8080'); $http_worker->count = 8; $http_worker->name = 'AdapterMan'; $http_worker->onWorkerStart = static function () { //init(); require __DIR__.'/start.php'; }; $http_worker->onMessage = static function ($connection, $request) { $connection->send(run()); }; Worker::runAll();
AdapterMan 源码 https://github.com/joanhey/AdapterMan/blob/master/src/AdapterFunctions.php#L10
<?php use Workerman\Protocols\Http; /** * Send a raw HTTP header * * @link https://php.net/manual/en/function.header.php */ function header(string $content, bool $replace = true, ?int $http_response_code = null): void { Http::header($content, $replace, $http_response_code); } /** * Remove previously set headers * * @param string $name The header name to be removed. This parameter is case-insensitive. * @return void * * @link https://php.net/manual/en/function.header-remove.php */ function header_remove(string $name): void { Http::headerRemove($name); //TODO fix case-insensitive } /** * Get or Set the HTTP response code * * @param integer $code [optional] The optional response_code will set the response code. * @return integer The current response code. By default the return value is int(200). * * @link https://www.php.net/manual/en/function.http-response-code.php */ function http_response_code(int $code = null): int { // int|bool return Http::responseCode($code); // Fix to return actual status when void } /** * Send a cookie * * @param string $name * @param string $value * @param integer $expires * @param string $path * @param string $domain * @param boolean $secure * @param boolean $httponly * @return boolean * * @link https://php.net/manual/en/function.setcookie.php */ function setcookie(string $name, string $value = '', int $expires = 0, string $path = '', string $domain = '', bool $secure = FALSE, bool $httponly = FALSE): bool { return Http::setcookie($name, $value, $expires, $path, $domain, $secure, $httponly); } function session_create_id(string $prefix = ''): string { return Http::sessionCreateId(); //TODO fix to use $prefix } function session_id(string $id = ''): string { return Http::sessionId($id); //TODO fix return session name or '' if not exists session } function session_name(string $name = ''): string { return Http::sessionName($name); } function session_save_path(string $path = ''): string { return Http::sessionSavePath($path); } function session_status(): int { if (Http::sessionStarted() === false) { return PHP_SESSION_NONE; } return PHP_SESSION_ACTIVE; } function session_start(array $options = []): bool { return Http::sessionStart(); //TODO fix $options } function session_write_close(): void { Http::sessionWriteClose(); } /** * Update the current session id with a newly generated one * * @param bool $delete_old_session * @return bool * * @link https://www.php.net/manual/en/function.session-regenerate-id.php */ function session_regenerate_id(bool $delete_old_session = false): bool { return Http::sessionRegenerateId($delete_old_session); } function set_time_limit(int $seconds): bool { // Disable set_time_limit to not stop the worker // by default CLI sapi use 0 (unlimited) return true; } /* function exit(string $status = ''): void { //string|int Http::end($status); } // exit and die are language constructors, change your code with an empty ExitException */
把session,cookies等使用封装函数代替了,是个不错的想法,但是不能全部直接移植使用,估计还需要更改一些东西
swoole4 是通过 hook 原生函数的方式去兼容各种库代码
AdapterMan https://github.com/joanhey/AdapterMan/blob/master/src/Adapterman.php#L39
<?php namespace Adapterman; use Exception; class Adapterman { public const VERSION = "0.5.3"; public const NAME = "Adapterman v". self::VERSION; private const FUNCTIONS = ['header', 'header_remove', 'http_response_code', 'setcookie', 'session_create_id', 'session_id', 'session_name', 'session_save_path', 'session_status', 'session_start', 'session_write_close', 'session_regenerate_id', 'set_time_limit']; public static function init(): void { try { self::checkVersion(); self::checkFunctionsDisabled(); // OK initialize the functions require __DIR__ . '/AdapterFunctions.php'; } catch (Exception $e) { fwrite(STDERR, self::NAME . ' Error:' . PHP_EOL); fwrite(STDERR, $e->getMessage()); exit; } fwrite(STDOUT, self::NAME . ' OK' . PHP_EOL); } /** * Check PHP version * * @throws Exception * @return void */ private static function checkVersion(): void { if (\PHP_MAJOR_VERSION < 8) { throw new Exception("* PHP version must be 8 or higher." . PHP_EOL . "* Actual PHP version: " . \PHP_VERSION . PHP_EOL); } } /** * Check that functions are disabled in php.ini * * @throws Exception * @return void */ private static function checkFunctionsDisabled(): void { foreach (self::FUNCTIONS as $function) { if (\function_exists($function)) { throw new Exception("Functions not disabled in php.ini." . PHP_EOL . self::showConfiguration()); } } } private static function showConfiguration(): string { $inipath = \php_ini_loaded_file(); $methods = \implode(',', self::FUNCTIONS); return "Add in file: $inipath" . PHP_EOL . "disable_functions=$methods" . PHP_EOL; } }
必须php8以上项目 用上workerman常驻内存 性能能提升一个量级
下图为laravel8 提升,其他项目比如thinkphp lumen Yii2 Slim 等 都可用此项目基础于 workerman 加速。
laravel8
thinkphp
lumen
Yii2
Slim
参考 workerman社区 https://www.workerman.net/q/9831
厉害
项目地址 https://github.com/joanhey/AdapterMan
看源码原理: 第一、禁止 php 自带函数的同时编写新的函数。 第二、提供新的启动入口使用
workerman
,同时把框架的核心加载代码,稍作修 改。这样就完美的接替了 php-fpm 。代码常驻内存,性 能提升还是肉眼可见的。当然这个里面的替换思路还是很有意思的。 第三、装上event
扩展 ,性能提升一个量级 , I/O 通知机制有效地安排基于 I/O、时间和信号的事件,epoll
linux内核支持 io多路复用https://pecl.php.net/package/event
event
扩展安装 此处忽略php.ini 通过 disable_functions 禁用一些函数
start.php
启动文件AdapterMan 源码 https://github.com/joanhey/AdapterMan/blob/master/src/AdapterFunctions.php#L10
把session,cookies等使用封装函数代替了,是个不错的想法,但是不能全部直接移植使用,估计还需要更改一些东西
swoole4 是通过 hook 原生函数的方式去兼容各种库代码
AdapterMan https://github.com/joanhey/AdapterMan/blob/master/src/Adapterman.php#L39
必须php8以上项目 用上workerman常驻内存 性能能提升一个量级
下图为
laravel8
提升,其他项目比如thinkphp
lumen
Yii2
Slim
等 都可用此项目基础于 workerman 加速。参考
workerman
社区 https://www.workerman.net/q/9831