背景:在更新一张表数据的同时通知其他服务作出相应的更改(考虑到性能问题,不即时操作),查阅资料后,选择了rabbitMQ消息队列实现。在更新数据表时将更新相关信息放到消息队列中,然后在其他服务运行的时候从消息队列中取出相关的信息,然后处理。
rabbitMQ使用:以下参照http://vtrtbb.iteye.com/blog/1280804
RabbitMQ是一个开源的基于AMQP(Advanced Message Queuing Protocol)标准,并且可靠性高的企业级消息系统,目前很多网站在用,包括reddit,Poppen.de等。
- 1. 安装RabbitMQ
- sudo apt-get install rabbitmq-server
- sudo /etc/init.d/rabbitmq-server start
- 2. 安装librabbitmq
- sudo apt-get install mercurial
- hg clone http://hg.rabbitmq.com/rabbitmq-c
- cd rabbitmq-c
- hg clone http://hg.rabbitmq.com/rabbitmq-codegen codegen
-
- 红色字体部分已过期不可用,此时rabbitmq-c文件目录下面只有一个readme文件说明新地址,浏览器打开新地址
- 找到新的下载地址:
- https://github.com/alanxz/rabbitmq-c/releases/download/v0.4.1/rabbitmq-c-0.4.1.tar.gz
- 下载后将包解压拷贝rabbitmq-c-0.4.1里面的文件到rabbitmq-c文件目录下
- autoreconf -i && ./configure && make && sudo make install
- 3. 安装php-rabbit扩展
- wget http://php-rabbit.googlecode.com/files/php-rabbit.r91.tar.gz
- tar -zxvf php-rabbit.r91.tar.gz
- cd php-rabbit.r91
-
- 红色字体部分已过期不可用,命令窗口会一直重复连接
- 换成下面的命令安装amqp
- wget http://pecl.php.net/get/amqp-1.0.4.tgz
tar zxf amqp-1.0.4.tgz && cd amqp-1.0.4
/usr/local/php5/bin/phpize (/usr/local/php5 php所在路径)
./configure --with-php-config=/usr/local/php5/bin/php-config --with-amqp
make && make install
- 4.编辑 php.ini 添加:
- extension=amqp.so
- 输出phpinfo看下是否扩展已经加载成功,have fun:)
下面是get方式获取消息队列内的信息php代码(用consume回调方式的时候,回调函数一直连接保持,没解决).
<?php
class RabbitMqModel extends BaseModel
{
private $conn; //rabbitMq服务器连接
private $channel; //rabbitMq虚拟主机
private $ex; //rabbitMq交换机
/**
* 创建队列需要用到的虚拟主机、交换机
*/
public function createRabbitMqSer()
{
$conn_args = array('host' => '172.18.107.66', 'port' => '5672', 'login' => 'guest',
'password' => 'guest','vhost'=>'/');
$this->conn = new AMQPConnection($conn_args);
if ($this->conn->connect()) {
echo "Established a connection to the broker <br />";
}
else {
echo "Cannot connect to the broker <br /> ";
}
//创建channel
$this->channel = new AMQPChannel($this->conn);
//创建exchange交换机
$this->ex = new AMQPExchange($this->channel);
$this->ex->setName('exchange');//创建名字
$this->ex->setType(AMQP_EX_TYPE_DIRECT);
$this->ex->setFlags(AMQP_DURABLE | AMQP_AUTODELETE);
$this->ex->declare();
}
/**
*
* 向队列里面添加信息
*/
public function setRabbitMqInfo()
{
$this->createRabbitMqSer();
//创建队列
$q = new AMQPQueue($this->channel);
//设置队列名字 如果不存在则添加
$q->setName('queue');
$q->setFlags(AMQP_DURABLE | AMQP_AUTODELETE);
echo "queue status: ".$q->declare();
echo "<br />";
echo 'queue bind: '.$q->bind('exchange','route.key');//将你的队列绑定到routingKey
//echo 'queue bind: '.$q->bind('exchange','route.'.$timestr);//将你的队列绑定到routingKey
echo "<br />";
//发布消息
$message = json_encode(array('Hello World!','php','c++'));
$this->channel->startTransaction();
echo "send: ".$this->ex->publish($message, 'route.key'); //将你的消息通过制定routingKey发送
//echo "send: ".$ex->publish($message, 'route.'.$timestr); //将你的消息通过制定routingKey发送
$this->channel->commitTransaction();
$this->conn->disconnect();
}
/**
*
* 获取队列里的信息
*/
public function getRabbitMqInfo ()
{
$this->createRabbitMqSer();
//创建队列
$q = new AMQPQueue($this->channel);
//设置队列名字 如果不存在则添加
$q->setName('queue');
$q->setFlags(AMQP_DURABLE | AMQP_AUTODELETE);
echo "queue status: ".$q->declare();
echo "<br />";
echo 'queue bind: '.$q->bind('exchange','route.key');//将你的队列绑定到routingKey
// $q->consume(array($this,'processMessage')); //需手动应答
while($q->declare()){
$messages = $q->get(AMQP_AUTOACK) ;
if ($messages){
echo "<pre>";
print_r(json_decode($messages->getBody(),true))."\n";
}
}
// disconnect
$this->conn->disconnect();
}
}
参考:
http://www.rabbitmq.com/install.html
http://blog.ftofficer.com/2010/03/translation-rabbitmq-python-rabbits-and-warrens/
http://code.google.com/p/php-rabbit/