啓動流程分析
在運行之前我們需要看一下官方文檔,了解兩個東西
執行入口文件
./bin/hyperf.php start
hyperf.php
#!/usr/bin/env php
<?php
ini_set('display_errors', 'on');
ini_set('display_startup_errors', 'on');
ini_set('memory_limit', '1G');
error_reporting(E_ALL);
! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
require BASE_PATH . '/vendor/autoload.php';
// Self-called anonymous function that creates its own scope and keep the global namespace clean.
(function () {
Hyperf\Di\ClassLoader::init();
/** @var Psr\Container\ContainerInterface $container */
$container = require BASE_PATH . '/config/container.php';
$application = $container->get(Hyperf\Contract\ApplicationInterface::class);
$application->run();
})();
在執行前會進行配置的掃描、依賴的處理、註解的掃描等等
通過ClassLoader::init(); 這裡面一堆東西,什麼類加載、註冊、掃描註解、類map等等大家可以慢慢看。
進入到container.php
<?php
/**
* Initialize a dependency injection container that implemented PSR-11 and return the container.
*/
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
use Hyperf\Di\Container;
use Hyperf\Di\Definition\DefinitionSourceFactory;
use Hyperf\Utils\ApplicationContext;
$container = new Container((new DefinitionSourceFactory(true))());
if (! $container instanceof \Psr\Container\ContainerInterface) {
throw new RuntimeException('The dependency injection container is invalid.');
}
return ApplicationContext::setContainer($container);
-
那麼上面DefinitionSourceFactory幹的事就是通過上面提到的ConfigProvider來解決依賴的問題,Hyperf的每個組件都需要有ConfigProvider文件,ConfigProvider在啓動的時候會進行處理,其中的denpendencies就是處理Inerface與對應的Definition。
-
那麼我們從vendor/hyperf/framework/src/ConfigProvider.php 可以看到ApplicationInterface的實現是ApplicationFactory
-
初始化命令行程序:symfony/console/application ,這是公共組件,Laravel也用的這個
解析輸入的command: 如 hyperf.php start 得到 vendor/hyperf/server/src/Command/StartServer ,繼承自Symfony/console/Command
並執行StartServer->execute
檢查環境 checkEnvironment
獲取 config/autoload/server.php 配置
解析配置
根據server裡面的type去初始化server
startServer.php
調用vendor/hyperf/server/src/Server->init
後面的事情就是初始化server了,type可以是SERVER_HTTP, SERVER_WEBSOCKET等
設置on 回調處理如onWorkerStart, onRequest等等
這裡會掃描路由,包括routes.php及使用註解的路由,組裝成url->handleClass的映射,如 api/v1/login -> /UserController->login 類似這樣的
調用server->start 啓動服務, 這裡後面就進入到swoole的執行流程了
以Http服務爲例子,當有請求進來時,會觸發onRequest事件
也就是vendor/hyperf/http-server/src/Server->onRequest
這個流程與其他框架就差不多了
獲取請求參數,從路由解析出controller->method
middleware處理
最後到達controller進行處理
返回response
部分代碼:
startServer.php
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->checkEnvironment($output);
$serverFactory = $this->container->get(ServerFactory::class)
->setEventDispatcher($this->container->get(EventDispatcherInterface::class))
->setLogger($this->container->get(StdoutLoggerInterface::class));
$serverConfig = $this->container->get(ConfigInterface::class)->get('server', []);
if (! $serverConfig) {
throw new InvalidArgumentException('At least one server should be defined.');
}
$serverFactory->configure($serverConfig);
Coroutine::set(['hook_flags' => swoole_hook_flags()]);
$serverFactory->start();
return 0;
}
Server.php
return [
'mode' => SWOOLE_PROCESS,
'servers' => [
[
'name' => 'http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9501,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],
],
],
],
'settings' => [
Constant::OPTION_ENABLE_COROUTINE => true,
Constant::OPTION_WORKER_NUM => swoole_cpu_num(),
Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid',
Constant::OPTION_OPEN_TCP_NODELAY => true,
Constant::OPTION_MAX_COROUTINE => 100000,
Constant::OPTION_OPEN_HTTP2_PROTOCOL => true,
Constant::OPTION_MAX_REQUEST => 100000,
Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024,
Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024,
],
'callbacks' => [
Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'],
Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'],
],
];
启动流程图
请求处理
参考:https://blog.csdn.net/weixin_39786534/article/details/110810520