如何使用RabbitMQ在CodeIgniter中重新加载代码更改



我使用CodeIgniter框架和RabbitMQ来执行耗时的活动,如发送电子邮件、生成PDF。

每当我更改PHP文件(比如库或控制器(中的代码时,直到我重新启动Apache,旧代码都由RabbitMQ执行。如何解决此问题?

控制器中的功能,

public function receive()
{
$this->db->reconnect();
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('generate_pdf', false, false, false, false);
echo "[*] Started listening to connections... To exit press CTRL+Cn";
$generate_pdf = function ($data)
{
$this->generatepdf->generate($data); // Generatepdf.php library -> generate() function
};
$channel->basic_qos(null, 1, null);
$channel->basic_consume('generate_pdf', '', false, true, false, false, $generate_pdf)
while ($channel->is_consuming())
{
$channel->wait();
}
}

从白蚁开始,

php index.php Controllerfile.php receive

这和预期的一样好。因此,当一个作业被推送到队列时,库文件Generatepdf.php中的generate()函数就会被调用并执行。

但是,如果我通过编辑器修改generate()函数,或者重新上传有更改的文件,则在重新启动Apache服务器之前,这些更改不会反映出来。

更改前的功能定义:

public function generate()
{
echo "Hello the data is 250";
}

输出:你好,数据是250

更改后的功能定义:

public function generate()
{
echo "Hello the data is 251";
}

重新启动Apache之前的输出:你好,数据是250

重新启动Apache后的输出:你好,数据是251

为什么会发生这种情况?如何执行以刷新文件中的更改?

您显示的代码包含以下循环:

while ($channel->is_consuming())
{
$channel->wait();
}

这句话的意思是";除非与RabbitMQ的连接断开,否则等待一条新消息,处理它,然后再等待一次,永远";。换句话说,它是一个无限循环,运行它的PHP进程不会退出,除非你杀死它

与我看到的一些描述相反,PHP是一种编译语言,而不是一种解释语言:当PHP进程被要求加载一个PHP代码文件时,它会查看一次,将其编译为机器友好的表示形式(称为"操作代码"(,然后不需要再查看它就可以多次执行其中的代码。因此,当您编辑文件时,已经运行的进程不会注意到,也不会编译您的新代码。

如果你想加载新代码,你需要退出无限循环,所以这个过程结束,然后开始一个新的循环,它将编译你的新代码。例如,您可以在循环中检查特定文件,测量它运行的时间,或者监听一条特殊消息,告诉它退出。然后,您可以使用类似";supervisorord";以确保脚本在退出时重新运行;cron";任务定期启动新副本。

还有一点:PHP的一个特性叫做";OpCache";它甚至在进程之间重用已编译版本的文件,以获得更好的性能。默认情况下,它会查看文件的时间戳来决定是否重新编译它,因此会"通知";如果您编辑了一个文件,但可以关闭该检查,以获得最大性能。如果这就是问题所在,那么您将在所有PHP代码中看到这一点,而不仅仅是您的RabbitMQ循环。

最新更新