hyperf框架-启动分析(单一入口)

啓動流程分析

在運行之前我們需要看一下官方文檔,了解兩個東西

執行入口文件

./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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值