php网站代码更新机制,[原创]Swoft源码剖析-代码自动更新机制

不同于php-fpm每次请求都会加载一次PHP代码,常驻型应用只会读取一次源文件,为了避免每次发布/调试代码都需要手动重启swoft应用,swoft提供了自动重载代码的功能。

文件重载管理进程

swoft注册了一个名为reload的Process,该进程会在系统引导的最后一个阶段,即swoole启动前启动。该Process会启动名为reload的Bean

//Swoft\Process\Bootstrap\Process\ReloadProcess.php

/**

* Relaod process

*

* @Process(name="reload", boot=true)

*/

class ReloadProcess implements ProcessInterface

{

/**

* @param \Swoft\Process\Process $process

*/

public function run(SwoftProcess $process)

{

$pname = App::$server->getPname();

$processName = sprintf('%s reload process', $pname);

$process->name($processName);

/* @var \Swoft\Process\Bootstrap\Reload $relaod */

$relaod = App::getBean(Reload::class);

$relaod->run();

}

//.....

}

文件更新监听Bean

//\Swoft\Process\Bootstrap\Reload::class

/**

* @Bean()

*/

class Reload

{

//code .....

/**

* 启动监听

*/

public function run()

{

$server = App::$server;

while (true) {

sleep($this->interval);

//FileHelper::md5File()负责递归的计算文件夹的md5,其实改名为FileHelper::md5Dir()更合适,因为他不接受非目录的文件作为参数

$md5File = FileHelper::md5File($this->watchDir);//$this->watchDir固定为@app别名对应的文件夹

if (strcmp($this->md5File, $md5File) !== 0) {

echo "Start reloading...\n";

$server->isRunning();

//md5和上次不一致就通知swoole重启服务

$server->getServer()->reload();

echo "Reloaded\n";

}

$this->md5File = $md5File;

}

}

}

代码自动重载的机制也很简单,每间隔几秒递归的计算@app目录下所有php文件的哈希值,发现文件夹的md5和之前的值有差别则通知swoole重启work进程。

Swoole WorkerStart事件

swoole会通知各个worker重启,触发swoole事件WorkerStart,具体的回调事件如下

namespace Swoft\Bootstrap\Server\ServerTrait.php;

/**

* OnWorkerStart event callback

*

* @param Server $server server

* @param int $workerId workerId

* @throws \InvalidArgumentException

*/

public function onWorkerStart(Server $server, int $workerId)

{

// Init Worker and TaskWorker

$setting = $server->setting;

$isWorker = false;

if ($workerId >= $setting['worker_num']) {

// TaskWorker

ApplicationContext::setContext(ApplicationContext::TASK);

ProcessHelper::setProcessTitle($this->serverSetting['pname'] . ' task process');

} else {

// Worker

$isWorker = true;

ApplicationContext::setContext(ApplicationContext::WORKER);

ProcessHelper::setProcessTitle($this->serverSetting['pname'] . ' worker process');

}

//触发一个Swoft服务事件```SwooleEvent::ON_START```,其监听者使用@ServerListener(event=SwooleEvent::ON_START)声明

$this->fireServerEvent(SwooleEvent::ON_WORKER_START, [$server, $workerId, $isWorker]);

//主要是重新扫描加载注解和Bean的重载

$this->beforeWorkerStart($server, $workerId, $isWorker);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值