我开发了一个Android应用程序,它可以订阅队列,也可以发布到其他队列。它一次向两个不同的队列发布相同的消息,其中一个队列名为" Queue"现在从appfog实例我需要订阅" Queue"并使用消息并将它们插入mysql db。
我使用codeigniter为上述目的创建了一个php独立应用程序。由于某种原因,工作者应用程序失去了与rabbitmq的连接。我想知道最好的方法。 appfog上的工作者应用程序如何才能维持应用程序的重启。
我需要用什么来解决上述问题。
我认为问题不在于rabbitmq连接。它是与mysql插入相关的代码。我检查了我的应用程序的崩溃日志,错误是" Mysql消失了#34;。一个php rabbitmq使用者的例子有接收消息和register_shutdown的回调。在接收回调我不能使用$ this代码点火器,因为它超出范围,我使用get_instance()。我不知道如何从rabbitmq客户端调用一个方法接收回调函数
控制器是
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
include(__DIR__ . '/php-amqplib/config.php');
use PhpAmqpLib\Connection\AMQPConnection;
class Welcome extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function index() {
//connect to rabbitmq and consume messages
//insert messages to mysql
//$this->messages = array();
$exchange = "router";
$queue = "abbiya";
$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$ch = $conn->channel();
/*
name: $queue
passive: false
durable: true // the queue will survive server restarts
exclusive: false // the queue can be accessed in other channels
auto_delete: false //the queue won't be deleted once the channel is closed.
*/
$ch->queue_declare($queue, false, true, false, false);
$ch->queue_bind($queue, $exchange, $queue);
/*
queue: Queue from where to get the messages
consumer_tag: Consumer identifier
no_local: Don't receive messages published by this consumer.
no_ack: Tells the server if the consumer will acknowledge the messages.
exclusive: Request exclusive consumer access, meaning only this consumer can access the queue
nowait:
callback: A PHP Callback
*/
$consumer_tag = "abbiya";
$ch->basic_recover(true);
$ch->basic_consume($queue, $consumer_tag, false, false, false, false, function($msg) {
$message_body = json_decode($msg->body);
$msg->delivery_info['channel']->
basic_ack($msg->delivery_info['delivery_tag']);
// Send a message with the string "quit" to cancel the consumer.
if ($msg->body === 'quit') {
$msg->delivery_info['channel']->
basic_cancel($msg->delivery_info['consumer_tag']);
}
$data = array(
'sender_id' => $message_body->r,
'receiver_id' => $message_body->s,
'message_content' => $message_body->m,
// 'sent_time' => $message_body->t,
'status' => 0
);
$ci =& get_instance();
$ci->Message_model->newMessage($data);
}
);
// Loop as long as the channel has callbacks registered
while (count($ch->callbacks)) {
$ch->wait();
}
register_shutdown_function(function() use ($ch, $conn) {
$ch->close();
$conn->close();
$this->index();
}
);
}
}
/* End of file welcome.php */
/* Location: ./application/controllers/welcome.php */
答案 0 :(得分:2)
首先,我必须说使用CodeIgniter创建一个消费者并且php可能不是一个好主意,除非你添加这样的东西
if( !$this->input->is_cli_request() ){
show_404(); // So they dont know this is an actual script
die();
}
从命令行运行nohup或daemonize it。
您可以使用codeigniter的$ this-&gt; db-&gt; reconnect();正常重新连接数据库。
我们已经使用php和CI为测试目的做了一些消费者。 我们将回调函数放入一个帮助程序中,并添加了一种让call_back函数返回false的方法,以便消费者在完成后停止侦听。
对于我们的生产系统,我们使用python,java或camel消费者,这些消费者更适合这项工作。