内蒙古乌海建设局网站,建站制作企业,网站推广及建设ppt,软件开发工程师考核指标Hyperf中的其它事项
关于 Hyperf 其它的内容我们就不多说了#xff0c;毕竟框架这东西用得多了自然也就熟悉了。最重要的是——我的水平还不足以去深入地分析这个框架#xff01;
好吧#xff0c;其它的功能大家可以去官方文档详细了解#xff0c;毕竟国人自己做的框架毕竟框架这东西用得多了自然也就熟悉了。最重要的是——我的水平还不足以去深入地分析这个框架
好吧其它的功能大家可以去官方文档详细了解毕竟国人自己做的框架文档和服务支持还是非常方便的。今天我们就来再简单讲讲其它的一些配置。
Nginx部署
第一个就是 Nginx 部署问题Nginx 做为现在顶流级别的应用服务器可以非常方便地实现 HTTP 服务、绑定域名、负载均衡等功能。在传统的 PHP-FPM 时代我们只需要指定 FastCGI 也就是那个 9000 端口或者 unixSocket 就可以了。其实也可以看出fastcgi_pass 这个词本身就是通过什么什么来执行的意思。fastcgi_pass 就是通过 fastcgi 来执行 PHP-FPM 程序从而实现应用程序的代理。
Swoole 本身启动的就是一个服务应用这种情况最方便的当然就是来一个反向代理搞定啦。
# 至少需要一个 Hyperf 节点多个配置多行
upstream hyperf {# Hyperf HTTP Server 的 IP 及 端口server 127.0.0.1:9501;server 127.0.0.1:9502;
}
server {# 监听端口listen 80; # 绑定的域名填写您的域名server_name www.testswoole.com;
location / {# 将客户端的 Host 和 IP 信息一并转发到对应节点 proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 转发Cookie设置 SameSiteproxy_cookie_path / /; secure; HttpOnly; SameSitestrict;# 执行代理访问真实服务器proxy_pass http://hyperf;}
}
这是官网的例子配置都比较简单也没什么多说的不过需要注意的是一定要配置 IP 的转发要不你在程序中获得的 IP 就是 127.0.0.1 那个了。这个只要配置过反向代理的应该都清楚也不多做解释了哦。
Supervisor部署
除了 Nginx 之外还推荐一个工具那就是 Supervisor 。它是一个进程管理工具本身 PHP-FPM 就可以自动管理进程同时我们之前也讲过在 Swoole 中如何管理进程。但是Supervisor 相对来说更加强大一些可以很方便地启动、监听和重启一个或多个进程。当一个进程意外被 kill 时它就会自动再把它重启或者拉起新的进程从而达到进程自动恢复的目的。
# 安装 epel 源如果此前安装过此步骤跳过
yum install -y epel-release
yum install -y supervisor
CentOS 的话直接运行上面两个命令行就可以安装 Supervisor 了。如果你有使用过 宝塔面板 之类的面板工具的话那就更方便了里面可以直接选择安装 Supervisor 并且能够图形界面化的管理。
如果你不爱使用面板类的工具的话那就还是跟着我一起向下配置吧。先来创建一个配置文件。
vim /etc/supervisord.d/hyperf.ini
在这个 .ini 文件中添加下面的内容。
# 新建一个应用并设置一个名称这里设置为 hyperf
[program:hyperf]
# 设置命令在指定的目录内执行
directory/home/www/6.框架/hyperf-skeleton/
# 这里为您要管理的项目的启动命令
commandphp ./bin/hyperf.php start
# 以哪个用户来运行该进程
userroot
# supervisor 启动时自动该应用
autostarttrue
# 进程退出后自动重启进程
autorestarttrue
# 进程持续运行多久才认为是启动成功
startsecs1
# 重试次数
startretries3
# stderr 日志输出位置
stderr_logfile/home/www/6.框架/hyperf-skeleton/runtime/stderr.log
# stdout 日志输出位置
stdout_logfile/home/www/6.框架/hyperf-skeleton/runtime/stdout.log
注意上面路径相关的内容要修改成你的项目路径哦。然后就可以启动 Supervisor 了。
supervisord -c /etc/supervisord.d/supervisord.conf
这一行的意思是以配置文件启动 Supervisor 主程序同时之前我们配置过的 .ini 文件中的程序都会运行起来。
[rootlocalhost supervisord.d]# ps -ef | grep skeleton
root 32162 32161 0 07:25 ? 00:00:00 skeleton.Master
root 32170 32162 0 07:25 ? 00:00:00 skeleton.Manager
root 32172 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.1
root 32173 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.2
root 32174 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.3
root 32175 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.4
root 32176 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.5
root 32177 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.6
root 32178 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.7
root 32179 32170 0 07:25 ? 00:00:00 skeleton.TaskWorker.8
root 32180 32170 0 07:25 ? 00:00:00 skeleton.Worker.0
不对呀我们程序名字怎么是 skeleton 而且 gerp php 也看不到内容。没错同时也不要慌张进入项目目录修改一下 .env 中 APP_NAME 我就修改成了 MNLZ 。接着重启一下 Supervisor 应用服务。
[rootlocalhost hyperf-skeleton]# supervisorctl restart hyperf
hyperf: stopped
hyperf: started
[rootlocalhost hyperf-skeleton]# ps -ef | grep MNLZ
root 32213 32161 1 07:29 ? 00:00:00 MNLZ.Master
root 32221 32213 0 07:29 ? 00:00:00 MNLZ.Manager
root 32223 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.1
root 32224 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.2
root 32225 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.3
root 32226 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.4
root 32227 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.5
root 32228 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.6
root 32229 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.7
root 32230 32221 0 07:29 ? 00:00:00 MNLZ.TaskWorker.8
root 32231 32221 0 07:29 ? 00:00:00 MNLZ.Worker.0
现在你可以试试 kill 一下不管是 TaskWorker 还是 Master kill 之后都会重新拉起新的进程。但是注意如果 Manager 出现问题了那可就拉不起任何子进程了。毕竟Manager 是整个 Swoole 中的管理进程。还记得我们之前讲过的进程模式相关的内容吗如果不记得了可以回去看看哦 【Swoole系列3.2】Swoole异步进程服务系统【Swoole系列3.2】Swoole 异步进程服务系统 。
最后为什么要使用 Supervisor 呢之前其实我们也讲过Swoole 中的一个异常或者错误就会导致进程被关闭为了保证有足够的子进程来处理请求Supervisor 就是非常好的选择特别是预防 Master 进程的突然中断。下面的一些命令行命令大家也可以了解一下。
# 启动 hyperf 应用
supervisorctl start hyperf
# 重启 hyperf 应用
supervisorctl restart hyperf
# 停止 hyperf 应用
supervisorctl stop hyperf
# 查看所有被管理项目运行状态
supervisorctl status
# 重新加载配置文件
supervisorctl update
# 重新启动所有程序
supervisorctl reload
Hyperf 核心生命周期
Hyperf 的生命周期其实分两个部分在官方文档上也就两段说明。我带着大家去翻源码再看一下。
在 Hyperf 中它没有像 Laravel 一样的 public/index.php 这样的请求入口文件。因为它是需要自己启动服务的所以它的全部入口都是 bin/hyperf.php 这个命令行文件。
框架生命周期
当我们执行 php bin/hyperf.php start 的时候实际上是 vendor/hyperf/server/src/Command/StartServer.php 这个文件中的命令被执行了。这一系列操作我们之前在学习 Laravel 命令行时也接触过。
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;}
在这个对象的 execute() 中我们就可以非常清楚地看到读取到了配置文件 config/autoload/server.php 中的内容然后交给一个 $serverFactory 对象去启动。
$serverFactory 的 configure() 方法会根据配置文件信息返回实际的原生 Swoole 服务对象。
public function configure(array $config)
{$this-config new ServerConfig($config);$this-getServer()-init($this-config);
}
public function getServer(): ServerInterface
{if (! $this-server instanceof ServerInterface) {$serverName $this-config-getType();$this-server new $serverName($this-container,$this-getLogger(),$this-getEventDispatcher());}return $this-server;
}
ServerConfig 对象会根据我们的配置文件生成一个格式化的配置对象。然后在下面的 getServer() 方法中根据 ServerConfig 对象的 getType() 返回值获得一个指定的 Server 对象。注意这个 getType() 返回的不是我们配置文件中的那个 type 属性哦。
class ServerConfig implements Arrayable
{// ......public function __construct(array $config []){// ......$this-setType($config[type] ?? Server::class)-setMode($config[mode] ?? 0)-setServers($servers)-setProcesses($config[processes] ?? [])-setSettings($config[settings] ?? [])-setCallbacks($config[callbacks] ?? []);}// ......
}
注意看这里的 setType() 它要拿的是整个 server.php 配置文件中最外层的 type 属性我们并没有定义这个值所以返回的就是 vendor/hyperf/server/src/Server.php 这个对象。接下来我们顺着这个对象的 init() 方法向下摸在 initServers() 方法中发现了一个 makeServer() 方法的调用感觉离胜利不远了哦。
protected function makeServer(int $type, string $host, int $port, int $mode, int $sockType)
{switch ($type) {case ServerInterface::SERVER_HTTP:return new SwooleHttpServer($host, $port, $mode, $sockType);case ServerInterface::SERVER_WEBSOCKET:return new SwooleWebSocketServer($host, $port, $mode, $sockType);case ServerInterface::SERVER_BASE:return new SwooleServer($host, $port, $mode, $sockType);}throw new RuntimeException(Server type is invalid.);
}
我擦不对呀SwooleHttpServer 又是什么鬼再进去看看我们就选第一个 SwooleHttpServer 。点过去之后总算真象大白了SwooleHttpServer 是一个命名空间别名真实的就是 Swoole 下面的各种服务器。
// vendor/swoole/ide-helper/src/swoole/Swoole/Http/Server.php
class Server extends \Swoole\Server
{
}
这一条线大家摸清楚了吧这就是我们说的第一个生命周期也就是整个框架运行起 Swoole 应用服务的生命周期。
请求与协程生命周期
另一个就是请求与协程的生命周期这里我就搬官方原话了其实这部分内容我们之前讲过。
Swoole 在处理每个连接时会默认创建一个协程去处理主要体现在 onRequest、onReceive、onConnect 事件所以可以理解为每个请求都是一个协程由于创建协程也是个常规操作所以一个请求协程里面可能会包含很多个协程同一个进程内协程之间是内存共享的但调度顺序是非顺序的且协程间本质上是相互独立的没有父子关系所以对每个协程的状态处理都需要通过 协程上下文 来管理。
总结
到这里我们整个 Hyperf 框架的学习就结束了同时整个 Swoole 系列也就告一段落了。这里先不煽情了毕竟后面还有一篇大总结大家有收获吗不管怎么样一步一步跟着我走下来相信多少都会有一点感悟和成长。更重要的如果有机会不如尝试在实战中运用一下这才是真正成长的最佳机会。
测试代码
https://github.com/zhangyue0503/swoole/tree/main/6.%E6%A1%86%E6%9E%B6/hyperf-skeleton
参考文档
Hyperf
Hyperf
Hyperf