RabbitMQ的安装与基本使用

    之前项目很紧,所以选用了一个非常简单易用的队列系统HTTPSQS,由于提供的功能较少,因而准备换用RabbitMQ。
    网上有很多非常棒的教程,比如:http://blog.csdn.net/column/details/rabbitmq.html。

    在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。如发送短信、邮件、过滤非法关键字等等。它还可以用于RPC。

    先看一张官方图:


    一、概念:
     Broker:简单来说就是消息队列服务器实体。
   Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
   Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
   Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
   Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
   vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
   producer:消息生产者,就是投递消息的程序。
   consumer:消息消费者,就是接受消息的程序。
   channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
二、安装RabbitMQ
     Ubuntu:
          sudo apt-get install erlang
          sudo apt-get install rabbitmq-server
     CentOS:
          1.先安装erlang
               yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel 
               yum -y install ncurses-devel 
               yum install ncurses-devel 
               wget http://www.erlang.org/download/otp_src_17.5.tar.gz
               tar -xzvf tp_src_17.5.tar.gz 
               cd tp_src_17.5
               ./configure --prefix=/usr/local/erlang --with-ssl --enable-threads --enable-smp-support --enable-kernel-poll --enable-hipe 
               make && make install
               配置erlang环境
               vi /etc/profile  #在最后添加下文
               ERL_HOME=/usr/local/erlang
               PATH=$ERL_HOME/bin:$PATH
               export ERL_HOME PATH
               使环境变量生效
               source /etc/profile
               测试一下是否安装成功,在控制台输入命令erl
          2.安装rabbitmq
               tar -zxvf rabbitmq-server-3.5.1.tar.gz 
               cd abbitmq-server-3.5.1
               make
               make TARGET_DIR=/usr/local/rabbitmq SBIN_DIR=/usr/local/rabbitmq/sbin MAN_DIR=/usr/local/rabbitmq/man DOC_INSTALL_DIR=/usr/local/rabbitmq/doc install
               报错处理:
                    /bin/sh: xmlto: command not found
                    /bin/sh: line 2: xmlto: command not found
                   解决:yum install xmlto
三、管理命令
       启动:rabbitmq-server start
       关闭:rabbitmqctl stop
       状态:rabbitmqctl status
四、插件
    启动web管理插件
        rabbitmq-plugins enable rabbitmq_management
        错误解决:
            Error: {cannot_write_enabled_plugins_file,"/etc/rabbitmq/enabled_plugins",            enoent}
            mkdir /etc/rabbitmq
            重新启动输入地址:localhost:15672,帐号默认为guest,密码guest,此帐号默认只能在本机访问。不建议打开远程访问。你可以创建一个帐户,并设置可以远程访问的角色进行访问。
            如:rabbitmqctl add_user ganxiangdong ganxiangdong
            rabbitmqctl  set_user_tags  ganxiangdong administrator
五、用户管理
     默认的 guest帐户相当于root帐户
     rabbitmqctl add_user username password 添加帐户
     rabbitmqctl change_password username newpassword 修改密码
     rabbitmqctl delete_user username 删除帐户
     rabbitmqctl list_users 列出所有帐户
     rabbitmqctl  set_user_tags  User  Tag 设置角色( administrator、 monitoring、 policymaker、 management、其它
     立即生效,不需重启
 六、安装PHP扩展(amqp)
     不一定非要安装扩展,你也可以直接下载类库:https://github.com/videlalvaro/php-amqplib。
     https://pecl.php.net/get/amqp-1.3.0.tgz
    tar -zxvf amqp-1.3.0.tgz & cd  amqp-1.3.0
     /usr/bin/phpize
     ./configure --with-php-config=/usr/bin/php-config --with-amqp
    在php.ini中extenstion部分写入extension=amqp.so
    最后phpinfo检查是否成功
七、使用PHP与之交互
      Produce端:
//设置连接属性
$connArgs = array(
     'host'           => 'localhost',
     'port'           => '5672',
     'login'           => 'guest',
     'password' => 'guest',
     'vhost'          => '/'
);

//创建RabbitMQ连接
$conn = new AMQPConnection($connArgs);
if (!$conn->connect()) {
    echo "Cannot connect to the broker <br/>\n ";
}

//创建channel
$channel = new AMQPChannel($conn);

//创建exchange
$exchangeName = 'exchange';
$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);//创建名字
$exchange->setType(AMQP_EX_TYPE_DIRECT);//设置为direct类型
$exchange->setFlags(AMQP_DURABLE);//持久化交换机,当代理重启动后依然存在,并包括它们中的完整数据
$exchange->setFlags(AMQP_AUTODELETE);//对交换机而言,自动删除标志表示交换机将在没有队列绑定的情况下被自动删除,如果从没有队列和其绑定过,这个交换机将不会被删除.

//发送消息
$routingKey = 'key_test';
for($i=0;$i<10;$i++){
     sleep(3);
     $message = 'Hello World '.$i;
    $exchange->publish($message,$routingKey);
}

//断开连接
$conn->disconnect();
Consumer端:
//设置连接属性
$connArgs = array(
                    'host'           => 'localhost',
                    'port'           => '5672',
                    'login'           => 'guest',
                    'password' => 'guest',
                    'vhost'          => '/'
);

//创建RabbitMQ连接
$conn = new AMQPConnection($connArgs);
if (!$conn->connect()) {
     echo 'cannot connect to the broker';
}

//创建channel
$channel = new AMQPChannel($conn);

//设置队列名称
$exchangeName = 'exchange';
$routingKey = 'key_test';    
$queueName = 'queue_test_1';
$queue = new AMQPQueue($channel);
$queue->setName($queueName);//设置名称
$queue->setFlags(AMQP_DURABLE);//持久化队列,当代理重启动后依然存在,并包括它们中的完整数据
$queue->declare();//声明此队列
$queue->bind('exchange',$routingKey);//使用某交换机,并绑定某路由关键字

//消费数据方式一:非阻塞方式
// while(true)
// {
//      sleep(1);
//      $envelope = $queue->get(AMQP_AUTOACK) ;//第一个参数表示自动ACK应答
//      if ($envelope){
//           $messages = $envelope->getBody();
//           echo $messages;
//      }
// }


//消费数据方式二:以阻塞模式消费数据(推荐)
while(true)
{
          $queue->consume('processMessage');//第一个参数表示要回调的方法名,第二个参数设置为AMQP_AUTOACK,表示自动ACK应答
}
/**
* 定义回调方法
*/
function processMessage($envelope, $queue)
{
     $messages = $envelope->getBody();#获取消息数据
     echo $messages;
     $queue->ack($envelope->getDeliveryTag()); //处理成功后,手动发送ACK应答
     //$queue->nack($envelope->getDeliveryTag()); //处理不成功,手动发送NO-ACK应答,放回队列中 
}

     八:特别说明:
     1.如果某一次消费数据没有ACK,则此条消息会记录为Unacknowledged,如果对于某一节点有连续三条则RabbitMQ认为此节点有故障,则不会再对它进行分发.当它断开后或一定时间后 Unacknowledged状态消息会重新放回交换机中。手动no-ack后此Message将会放回队列中且不会再转发给此节点。
     2.对于计算密集型的工作,我们需要建立多个Consumer,对于多个 Consumer,默认的分发机制是“公平分发”,将第n个发给第n个Consumer,超过个数取n的模。
     3.Exchange中的类型有 :direct, topic 和fanout。
          direct: 通过routingKey和exchange决定的那个 唯一 的queue可以接收消息。
              topic : 所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息,direct的区别是它的routingkey可 以模糊匹配,#代表一个或多个字符,*代表任何字符 。一般为确保程序严谨性而使用direct。注意当 使用RoutingKey为#,Exchange Type为topic的时候相当于使用fanout
          fanout:是广播模式,所有bind到此exchange的queue都可以接收消息 ,即该一个Message可以对应多个Consumer,应用场景举例:生产了了添加到购物车的Message,一个Consumer写推荐商品日志,一个Consumer写购物车表。
     4.两个不相同的queue名的队列绑定到同一exchange和rotingky上,此时相当于同一queue名的fanout广播模式,两个queue都会得都到
所有Message。如图所示:
5.RPC的实现流程:


参考资料:http://blog.csdn.net/column/details/rabbitmq.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值