如何使用 RabbitMQ 重新加载 CodeIgniter 中的代码更改?
How to reload code changes in CodeIgniter with RabbitMQ?
我将 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+C\n";
$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
正如预期的那样工作正常。所以当一个job被push到队列中时,库文件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 代码文件,它 看一次 ,将其编译为 machine-friendly 表示(称为“操作代码”),然后不需要再次查看它以多次执行其中的代码。因此,当您编辑文件时,已经 运行 的进程不会注意到,也不会编译您的新代码。
如果你想加载新的代码,你需要退出死循环,所以这个过程结束,然后开始一个新的,它会编译你的新代码。例如,您可以检查特定文件的循环,测量它已经 运行 的时间,或者监听告诉它退出的特殊消息。然后,您可以使用“supervisord”之类的东西来确保脚本在退出时 re-run,或者只是有一个“cron”任务来定期启动一个新副本。
另外一点:PHP 有一个称为“OpCache”的功能,它甚至在进程之间重用文件的编译版本,以获得更好的性能。默认情况下,它会查看文件的时间戳来决定是否重新编译它,因此如果您编辑文件,它会“发出通知”,但可以关闭该检查以获得最佳性能。如果那是问题所在,您会在 all PHP 代码中看到它,而不仅仅是您的 RabbitMQ 循环。
我将 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+C\n";
$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
正如预期的那样工作正常。所以当一个job被push到队列中时,库文件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 代码文件,它 看一次 ,将其编译为 machine-friendly 表示(称为“操作代码”),然后不需要再次查看它以多次执行其中的代码。因此,当您编辑文件时,已经 运行 的进程不会注意到,也不会编译您的新代码。
如果你想加载新的代码,你需要退出死循环,所以这个过程结束,然后开始一个新的,它会编译你的新代码。例如,您可以检查特定文件的循环,测量它已经 运行 的时间,或者监听告诉它退出的特殊消息。然后,您可以使用“supervisord”之类的东西来确保脚本在退出时 re-run,或者只是有一个“cron”任务来定期启动一个新副本。
另外一点:PHP 有一个称为“OpCache”的功能,它甚至在进程之间重用文件的编译版本,以获得更好的性能。默认情况下,它会查看文件的时间戳来决定是否重新编译它,因此如果您编辑文件,它会“发出通知”,但可以关闭该检查以获得最佳性能。如果那是问题所在,您会在 all PHP 代码中看到它,而不仅仅是您的 RabbitMQ 循环。