继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

RabbitMQ教程之一:安装及简介

秋名山车神
关注TA
已关注
手记 52
粉丝 1.9万
获赞 4696
RabbitMQ到底是什么?

RabbitMQ是一个程序与程序之间通信的方法,或者可以理解为一种专用的通道,专门用来负责消息的读取和写入。应用程序通过在RabbitMQ中读写消息来通信,程序与程序之间无需专门的链接,而是直接通过RabbitMQ来进行数据的读写。RabbitMQ将会采用异步的方式来分发消息,是一种经典的生产者与消费者的模式,多个消费者由RabbitMQ来负责协调,并且保证每一条消息都能得到可靠的执行。假如一条消息在执行过程中出现了错误,RabbitMQ并不会放弃这条消息,而是专由其他的消费者来处理这条消息。

RabbitMQ和Celery到底有什么区别?

上面我们已经提到过,RabbitMQ是负责消息的生产和消费,我们可以理解为,RabbitMQ是一个仓库的中转站,所有的程序消息都发送给RabbitMQ,然后由RabbitMQ来负责把这些消息来运输给消费者。但是RabbitMQ的侧重点在于,消息的读写。比如说我们有一个仓库A,我想把仓库A里面的全部货物,经过不同的路线,最终运输到仓库B里面。如果我们使用RabbitMQ,是可以完成这种操作,但是这其中包含了大量复杂的逻辑,我们需要自己去写。于是有人就提供了一种现成的方案,那就是Celery。

Celery主要负责的就是异步的任务队列,它本身不提供任何数据的存取,只关注如何把数据,异步,安全,高效,可靠的运输到另一个地点,并且在对方处理完成以后,再把响应数据通知给对应的方法。

我们拿爬虫来讲,假如我要爬一个网站A,如果按照正常的逻辑。发送一个请求到网站A,然后网站A收到了我的请求,把响应的页面传给我,我再负责解析。这其中就包含了一个问题,比如说A网站的服务器很卡,在我发送数据以后,到他处理完成,这段过程用了三四秒的时间。那么这段时间我的程序一直是处于一种等待状态,等待响应的完成,这样就造成了大量的资源浪费。

使用Celery的好处就是,在我们请求发送出去以后,Celery就立刻开始去发送下一个任务,它会把所有的任务都快速的发送出去,并不等待任务响应完成。当某一个任务响应回来时,Celery再去通知具体的人来处理响应的数据,然后继续分发任务。

所以RabbitMQ和Celery最大区别就是,RabbitMQ提供了一种可靠的消息存取的服务,而Celery负责高效的分发这些消息。

在Ubuntu安装RabbitMQ

这里我使用的是vultr的云主机,在之前的文章中有介绍如何注册创建vultr云主机,不会的请戳链接,这里将不再介绍任何关于创建和连接的问题,当然也可以使用自己本地的虚拟机或者是其他的云服务器,如阿里云,谷歌云。

这里我们使用的是Ubuntu 14.04 x64版本的

首先为了避免各种签名错误,我们把公钥加入可信任的列表:

wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo apt-key add rabbitmq-signing-key-public.asc

当我们看到控制台显示:

OK

说明我们导入公钥成功。

然后我们开始更新和安装RabbitMQ:

sudo apt-get update
sudo apt-get install rabbitmq-server

当控制台询问我们是否安装的时候,输入y然后回车。

当看到结尾出现如下信息说明安装成功:

Adding group rabbitmq' (GID 110) ... Done. Adding system userrabbitmq’ (UID 105) …
Adding new user rabbitmq' (UID 105) with grouprabbitmq’ …
Not creating home directory `/var/lib/rabbitmq’.

  • Starting message broker rabbitmq-server [ OK ]
    Processing triggers for libc-bin (2.19-0ubuntu6.11) …
    Processing triggers for ureadahead (0.100.0-16) …

RabbitMQ安装成功以后,会建立一个默认的guest账户,用户名和密码都是guest。我们在shell里面输入rabbitmqctl status可以查看RabbitMQ的运行情况。

看到如下输出,说明我们RabbitMQ已经成功运行:

img

输入rabbitmqctl stop将关闭RabbitMQ服务器,看到如下信息说明关闭成功:

Stopping and halting node rabbit@chenshen …
…done.

此时再次输入rabbitmqctl status,将会看到如下错误信息提示我们没有运行RabbitMQ:

img

那么我们如何启动RabbitMQ呢,有些同学可能会想,肯定是输入rabbitmqctl start。不过很可惜,RabbitMQ并不是依靠这种方式来启动的,而是使用另一个命令:rabbitmq-server -detached,参数-detached是使用守护进程在后台运行,如果不加此参数,则关闭命令行后RabbitMQ会自动退出。

运行以后我们会得到一个警告:

Warning: PID file not written; -detached was passed.

需要注意的是,这个警告是正常的警告,并非是异常信息,如果不放心可以查看RabbitMQ的运行日志和错误日志:

cat /var/log/rabbitmq/startup_log
cat /var/log/rabbitmq/startup_err

看到这种如下信息,说明我们启动正常:

img

需要注意的是,上面的警告信息是正常的,并非是我说的,而是官方文档说的:

Options
  • -detached

    Start the server process in the background. Note that this will cause the pid not to be written to the pid file.For example:rabbitmq-server -detachedRuns RabbitMQ AMQP server in the background.

大概的意思就是,如果我们加了-detached参数在后台运行的话,这会让pid不能被写入pid文件。

Hello World

程序员惯例,什么都先来一个Hello World。

安装pika

我们只是安装了RabbitMQ,但是我们如果想要在Python中使用,就需要安装具体的库:

RabbitMQ使用的是AMQP协议。要使用它,你就必须需要一个使用同样协议的库。

py-amqplib
txAMQP
pika

官方文档中,使用的pika,所以我们也使用pika。

警告:需要注意的是,此时我们是在另一台电脑安装,并非在服务器安装!

我使用的是Windows10操作系统,Python版本为3.5,请大家保持同步。

使用下面的命令安装:

pip install pika -i https://pypi.douban.com/simple/

看到如下信息说明安装成功:

Successfully installed pika-0.10.0

注意:我这里默认安装最新的,是0.10.0版本,随着时间的推移,可能会有较大的变化,如果大家哪天发现按照本文无法正常操作,有可能是版本升级的问题。此时,大家可以这么做:

pip uninstall pika
pip install pika==0.10.0 -i https://pypi.douban.com/simple/

卸载后,指定安装版本。

终于要开始了

我们在远程连接RabbitMQ之前,需要新建一个用于远程连接的用户,默认的guest用户只接受127.0.0.1的本地连接。

警告:此时我们的操作又是在服务器了!

* 查看用户列表
sudo rabbitmqctl list_users

可以看到,我们只有一个默认的guest用户,它的权限是administrator。

警告兼友情提示:下面的命令不要直接复制,因为中文编码和shell的编码不一样,你直接在上面改会造成,看似没有字符,实际上还有一些中文字符编码在里面,导致你到时候用户名不是你建的用户名,而是有一些你看不到的编码在里面。当然,这种可能性非常小,但是直接复制报错的几率是很大的,因为你没把字符编码删干净,聪明的人都知道在本地的文本文档改好,然后再复制运行。

* 创建用户,如果你连用户名和密码改成自己想设置的都不知道,我不建议你学编程了
sudo rabbitmqctl add_user 用户名 密码
* 查看一下有没有创建成功,可以看到新建了一个用户cheshen[],他的权限为空
sudo rabbitmqctl list_users
* 赋予超级管理员权限,这个用户名一看就是你上面建的好伐
sudo rabbitmqctl set_user_tags 用户名 administrator
* 再次查看
sudo rabbitmqctl list_users
* 最重要的一步,设置监听请求的地址
rabbitmqctl set_permissions -p "/" 用户名 ".*" ".*" ".*"

Listing users …
cheshen [administrator]
guest [administrator]
…done.

终于可以写代码了!!!

开始写代码

本地Windows环境了

新建文件send.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2017-04-02 01:20:41
# @Author  : 车神 (meteorshield@gmail.com)
# @Link    : http://www.cheshen.wiki
# @Version : $Id$

import pika

# 就是我们刚才创建的那个
credentials = pika.PlainCredentials('用户名', '密码')
parameters = pika.ConnectionParameters(credentials=credentials)

parameters = pika.ConnectionParameters('服务器IP',5672,'/',credentials)    
connection = pika.BlockingConnection(parameters)

channel = connection.channel()

channel.queue_declare(queue='hello')

print(' [*] Waiting for messages. To exit press CTRL+C')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % (body,))

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)

channel.start_consuming()

新建receive.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2017-04-02 01:20:41
# @Author  : 车神 (meteorshield@gmail.com)
# @Link    : http://www.cheshen.wiki
# @Version : $Id$

import pika
credentials = pika.PlainCredentials('用户名', '密码')
parameters = pika.ConnectionParameters(credentials=credentials)

parameters = pika.ConnectionParameters('服务器IP',5672,'/',credentials)    
connection = pika.BlockingConnection(parameters)

channel = connection.channel()

channel.queue_declare(queue='hello')

print(' [*] Waiting for messages. To exit press CTRL+C')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % (body,))

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)

channel.start_consuming()

在本地的控制台输入:

python send.py

然后会看到:

[x] Sent ‘Hello World.’

启动另一个命令行再输入:

python receive.py

然后会看到:

[*] Waiting for messages. To exit press CTRL+C
[x] Received b’Hello World.’

这个进程并不会退出,而是等待我们发送新的信息,再次运行python send.py可以看到receive的窗口再次输出信息。

运行可能会报错:pika.exceptions.ConnectionClosed

这是因为我们的服务器在美国,连接超时了,多次连接,或者开启系统代理就可以了。

多来几次就可以了

下章我们详细解释这些方法都是干啥的。

后记

感谢大家的支持,本文原创作者:秋名山车神

转载请注明出处,大家有任何的问题,都可以通过我博客上的联系方式与我取得联系。

END

打开App,阅读手记
33人推荐
发表评论
随时随地看视频慕课网APP

热门评论

send.py 和 receive.py 咋一样的?

send.py 应该如下

import pika# 就是我们刚才创建的那个
...这部分正确
channel.queue_declare(queue='hello')

channel.basic_publish(exchange='',                      routing_key='hello',                      body='Hello World!')
print " [x] Sent 'Hello World!'"
connection.close()


还是有很多不懂,希望再讲一些通俗的东西可以吗

查看全部评论