rabbitmq的队列服务功能

RabbitMQ是一个基于Erlang实现的消息队列服务,遵循AMQP通信协议,是比较流行通用的异步消息队列服务。

背景知识,Erlang是一个结构化,动态类型编程语言,内建并行计算支持。使用Erlang编写的程序通常有许多轻量级进程组成,通过消息传递互相通信,进程间上下文切换比C的线程切换高效地多。)

首先下载安装Erlang,然后下载rabbitmq的rpm安装包(我的环境是fedora 14),执行下面的命令安装服务

[root@fedora Projects]# rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
[root@fedora Projects]# yum install rabbitmq-server-2.8.2-1.noarch.rpm
可能还需要下载一些erlang的依赖包,安装有点慢,不过yum会帮我们搞定这些。安装完毕后可以启动服务了

[root@fedora Projects]# service rabbitmq-server start
Starting rabbitmq-server: SUCCESS
rabbitmq-server.
[root@fedora Projects]# 
然后接着安装php的扩展包,我在rabbitmq的官网上找了一个 php-amqplib,安装方法如下:

git clone git://github.com/videlalvaro/php-amqplib.git

cd php-amqplib/
make

这个扩展并不是提供一个动态链接库,而是提供了一些头文件的封装,我们先进入demo目录来测试一下能否正常运行(如果遇到下面这个错误,需要安装php-bcmath扩展)

[root@fedora demo]# php amqp_consumer.php 
PHP Fatal error:  Call to undefined function PhpAmqpLib\Wire\bcmod() in /home/fedora/Projects/php-amqplib/PhpAmqpLib/Wire/AMQPWriter.php on line 34
安装完php-bcmath后再运行php amqp_consumer.php

[root@fedora demo]# php amqp_consumer.php 
程序在此处挂起等待生产者发布消息,然后我们打开另外一个终端模拟生产者

[root@fedora demo]# php amqp_publisher.php some text to publish
然后再看消费者,已经拿到消息如下:

--------
some text to publish
--------
再测试发送消息如下,则消费者程序退出。可以看出php的扩展包已经可以正常运行了。

[root@fedora demo]# php amqp_publisher.php quit
下面我们来看看代码中是怎么用的吧,首先程序需要包含两个基本的头文件,都是在demo目录下

autoload.php

<?php

require_once(__DIR__ . '/../vendor/symfony/Symfony/Component/ClassLoader/UniversalClassLoader.php');

use Symfony\Component\ClassLoader\UniversalClassLoader;

$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
            'PhpAmqpLib' => __DIR__ . '/..',
        ));

$loader->register();

config.php

<?php
include_once(__DIR__.'/autoload.php');

define('HOST', 'localhost');
define('PORT', 5672);
define('USER', 'guest');
define('PASS', 'guest');
define('VHOST', '/');

//If this is enabled you can see AMQP output on the CLI
define('AMQP_DEBUG', false);
消费者的代码如下:

<?php

include(__DIR__ . '/config.php');
use PhpAmqpLib\Connection\AMQPConnection;

$exchange = 'router';
$queue = 'msgs';
$consumer_tag = 'consumer';

/**
* 生产者消费者一样的代码
*/

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$ch = $conn->channel();

$ch->queue_declare($queue, false, true, false, false);

$ch->exchange_declare($exchange, 'direct', false, true, false);

$ch->queue_bind($queue, $exchange);


/**
* 注册消息回调函数
*/

function process_message($msg) {

    echo "receive message : " . $msg->body . "\n";

    $msg->delivery_info['channel']->
        basic_ack($msg->delivery_info['delivery_tag']);

}
$ch->basic_consume($queue, $consumer_tag, false, false, false, false, 'process_message');

/**
* 关闭连接回调
*/
function shutdown($ch, $conn){
    $ch->close();
    $conn->close();
}
register_shutdown_function('shutdown', $ch, $conn);

/**
* 循环等待消息
*/

while (count($ch->callbacks)) {
    $ch->wait();
}
?>
生产者的代码如下:

<?php

include(__DIR__ . '/config.php');
use PhpAmqpLib\Connection\AMQPConnection;
use PhpAmqpLib\Message\AMQPMessage;

$exchange = 'router';
$queue = 'msgs';

/**
* 生产者消费者一样的代码
*/

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
$ch = $conn->channel();

$ch->queue_declare($queue, false, true, false, false);

$ch->exchange_declare($exchange, 'direct', false, true, false);

$ch->queue_bind($queue, $exchange);

/**
* 发布消息到消息队列
*/

$msg_body = "hello consumer";

$msg = new AMQPMessage($msg_body, array('content_type' => 'text/plain', 'delivery_mode' => 2));
$ch->basic_publish($msg, $exchange);

$ch->close();
$conn->close();
?>

分别执行消费者和生产者,我们可以看到消费者端获取到了“hello consumer”的文本信息

此外,看上面创建队列,创建连接的参数很多,可以进行比较详细的个性化定制。rabbitmq虽然功能强大,在软件领域里面得到很多的应用,可是针对互联网的应用场景可能还是redis可以更好地胜任。所以同样是作为消息队列,两者也是各有所长。官方有提供各种语言版本的扩展支持,python的代码感觉要简单得多,我找的这个php的扩展使用起来还是麻烦了点,如果是提供动态链接库的扩展方式就好了。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值