01、windows安装
--erlang安装:
--RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang
--下载地址:http://www.erlang.org/downloads
--安装:
--选择安装文件夹,然后一路点击即可
--配置环境变量:
--安装路径/bin 添加到path中即可
--rabbitmq安装:
--下载:http://www.rabbitmq.com/download.html
--安装
--进入安装目录 /sbin
--执行命令:rabbitmq-plugins enable rabbitmq_management
--执行命令:rabbitmqctl status
--最后点击/sbin目录下的 rabbitmq-server.bat 文件
--访问:http://localhost:15672 账户密码都是 guest
02、windows下实现远程访问
--rabbit 登陆的若干事宜:
--进入安装的/sbin目录:
--rabbitmqctl list_users 查看现有用户有哪些
--创建一个用户:rabbitmqctl add_user 【用户名】 【密码】
--记住没有赋予权限之前,查看用户显示的是:用户名 []
--赋予权限之后显示为:用户名 [adminstartor]
--rabbitmqctl set_user_tags 【用户名】 administrator 设置用户的权限等级
--management:用户可以访问管理插件
--policymaker:用户可以访问管理插件,并管理他们有权访问的vhost的策略和参数。
--monitoring:用户可以访问管理插件,查看所有连接和通道以及与节点相关的信息。
--administrator:用户可以做任何监视可以做的事情,管理用户,vhost和权限,关闭其他用户的连接,并管理所有vhost的政策和参数。
--给用户赋予外部登陆资格:
--rabbitmqctl set_permissions -p / root ".*" ".*" ".*"
--rabbitmqctl set_permissions [-pvhostpath] {user} {conf} {write} {read}
--Vhostpath:虚拟主机,表示该用户可以访问那台虚拟主机;
--user:用户名。
--Conf:一个正则表达式match哪些配置资源能够被该用户访问。
--Write:一个正则表达式match哪些配置资源能够被该用户设置。
--Read:一个正则表达式match哪些配置资源能够被该用户访问。
--查看rabbitmq的用户主机权限:
--rabbitmqctl list_user_permissions root
--删除用户:rabbitmqctl delete_user username
--修改密码:rabbitmqctl change_password {username} {newpassword}
03、使用rabbbitmq的案例:收发消息
--rabbitmq:有三个角色 生产者 队列 消费者
--发送消息的称为生产者
--接收消息的称为消费者
--队列:就是一个巨大的缓存空间,消息存储在队列中。多个生产者可以在消息队列中加入数据,多个消费者也可以从消息队列中取出数据
--rabbit做的事情就是:管理队列,接收消息,分发消息
--参考教程:
--http://rabbitmq.mr-ping.com/tutorials_with_python/[2]Work_Queues.html
--发送消息的示例:
--生产者:
--创建一个send.py,文件如下:
import pika
# 连接rabbitmq
credentials = pika.PlainCredentials('root', 'root123456')
connection =pika.BlockingConnection(pika.ConnectionParameters('192.168.1.100', '5672', '/', credentials))
channel = connection.channel()
# 发送消息之前,确认队列存在,通过创建的方式如果存在则不起作用,如果不存在则创建一个
channel.queue_declare(queue='hello')
# exchange 是交换机,消息是不能直接放入队列的得通过交换机进行,这里使用空字符串表示默认的交换机。默认交换机允许我们指定将消息放入到那个队列中
# routing_key 是我们指定交换机名称的参数
# body 是需要交换的消息
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print(" [x] Sent 'Hello World!'")
# 在传输消息之后需要关闭连接,将缓存的数据刷新到队列中
connection.close()
--消费者:
--创建一个receive.py,文件如下:
import pika
# 连接rabbitmq
credentials = pika.PlainCredentials('root', 'root123456')
connection =pika.BlockingConnection(pika.ConnectionParameters('192.168.1.100', '5672', '/', credentials))
channel = connection.channel()
# 这里重复声明队列是推荐做法,避免出现队列没有申明的尴尬情况
channel.queue_declare(queue='hello')
# 被回调的函数,该函数定义的参数需要到channel.basic_consume()中去看看
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
# 回调函数
channel.basic_consume('hello', callback, True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
--被回调的函数参数如下:pika/channel.py文件
:param callable on_message_callback: The function to call when consuming with the signature on_message_callback(channel, method, properties, body), where
--channel: pika.Channel
--method: pika.spec.Basic.Deliver
--properties: pika.spec.BasicProperties
--body: bytes
04、rabbitmq的使用案例:工作队列,一个sender 多个worker 且 worker执行失败会发给其他的worker
--工作队列:是为了避免等待一些占用大量资源、时间的操作。当我们把任务(Task)当作消息发送到队列中,一个运行在后台的工作者(worker)进程就会取出任务然后处理。当你运行多个工作者(workers),任务就会在它们之间共享。
--在网络应用中是非常有用的,它可以在短暂的HTTP请求中处理一些复杂的任务。
--new_task.py 发送任务,一个点表示停顿一秒,具体代码如下:
import pika
import sys
# 连接rabbitmq
credentials = pika.PlainCredentials('root', 'root123456')
connection =pika.BlockingConnection(pika.ConnectionParameters('192.168.1.100', '5672', '/', credentials))
channel = connection.channel()
# 发送消息之前,确认队列存在,通过创建的方式如果存在则不起作用,如果不存在则创建一个
channel.queue_declare(queue='hello')
# exchange 是交换机,消息是不能直接放入队列的得通过交换机进行,这里使用空字符串表示默认的交换机。默认交换机允许我们指定将消息放入到那个队列中
# routing_key 是我们指定交换机名称的参数
# body 是需要交换的消息
message = ' '.join(sys.argv[1:]) or "Hello World!"
print(message)
channel.basic_publish(exchange='', routing_key='hello', body=message)
print(" [x] Sent 'Hello World!'")
# 在传输消息之后需要关闭连接,将缓存的数据刷新到队列中
connection.close()
--两个worker,代码一致,都是从同一个队列取出任务,所以这种模式下很容易扩展后台。具体代码如下:
--worker1.py
--worker2.py
--一共两个文件,代码一致
import pika
import time
# 连接rabbitmq
credentials = pika.PlainCredentials('root', 'root123456')
connection =pika.BlockingConnection(pika.ConnectionParameters('192.168.1.100', '5672', '/', credentials))
channel = connection.channel()
# 这里重复声明队列是推荐做法,避免出现队列没有申明的尴尬情况
channel.queue_declare(queue='hello')
# 被回调的函数,该函数定义的参数需要到channel.basic_consume()中去看看
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
time.sleep(str(body).count('.'))
print("[x] Done")
ch.basic_ack(delivery_tag=method.delivery_tag)
# 回调函数
# channel.basic_consume('hello', callback, True)
channel.basic_consume('hello', callback)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
任务启动:
--启动消费者:
--python worker1.py
--python worker2.py
--启动生产者:
--python new_task.py First message.
--python new_task.py Second message..
--python new_task.py Third message...
--python new_task.py Fourth message....
--python new_task.py Fifth message.....
--说明:执行中队列会将任务轮流给不同队列,所以看到的就是
[x] Received b'Second message..'
[x] Done
[x] Received b'Fourth message....'
[x] Done
[x] Received b'First message.'
[x] Done
[x] Received b'Third message...'
[x] Done
[x] Received b'Fifth message.....'
[x] Done
--在工作队列模式中,我们知道如果worker工作失败中断,队列是不知道的。所以需要消息确认机制:
--为了防止消息丢失,RabbitMQ提供了消息响应(acknowledgments)。消费者会通过一个ack(响应),告诉RabbitMQ已经收到并处理了某条消息,然后RabbitMQ就会释放并删除这条消息。
--消息响应默认是开启的,之前使用no_ack=True标识把它关闭,在worker.py中将basic_comsume()函数的参数no_ack=True移除即可
--为了防止形成死循环,可以通过命令查看就绪的消息和未知的消息
--rabbitmqctl list_queues name messages_ready messages_unacknowledged