要正常使用Celery(4.2.1版本)还需要RabbitMQ,Redis,还可以下载eventlet或gevent用于并发执行。
1. 配置RabbitMQ
详细的RabbitMQ的安装配置可以参考这篇文章:
强调几个需要注意的点:
1.1 最好配置一下RabbitMQ的路径,这样可以直接使用RabbitMQ的若干.bat格式的指令。
1.2 启动RabbitMQ的管理插件:
rabbitmq-plugins enable rabbitmq_management
rabbitmq-plugins是一个.bat文件,如果没有设置路径则需要进入相应的安装目录下再执行该命令。
安装插件后要重启下RabbitMQ服务:
net stop RabbitMQ && net start RabbitMQ
1.3 添加用户和用户权限
RabbitMQ默认有一个用户,用户名为guest,密码为guest。可以将这个默认用户删除掉。
rabbitmqctl.bat delete_user username
或者修改密码:
rabbitmqctl change_password userName newPassword
新增用户:
rabbitmqctl add_user username password
guest用户的角色是administrator,我们为新增用户也可以设置角色:
rabbitmqctl set_user_tags username administrator
注意:administrator一定要拼写正确,因为如果拼写错误(例如拼写为adminstrator),那么就会为按照拼写的内容设置角色(即此时用户的角色为adminstrator),而不会报错。
1.4 设置权限
使用RabbitMQ时要指定一个路径,比如username:password@localhost://,此时必须要设定用户名为username的用户在'/'路径上的权限,同理,如果是username:password@localhost:/mytest,则要设置用户名为username的用户在mytest路径上的权限。
rabbitmqctl set_permissions -p 路径 用户 ConfP配置权限 WriteP写权限 ReadP读权限
1.5 如果成功启动了插件,上述1.3和1.4的功能可以在客户端中进行可视化操作完成。
打开浏览器输入:localhost:15672
如果没有删除guest用户,可以用guest/guest登录。如果已经删除,则先需要使用命令行创建一个用户,然后使用该用户登录。
登录后选择Admin标签卡,填入要添加的用户信息后,点击Add User按钮
新增的用户在用户列表中的Can Access Virtual Hosts为空:
点击用户名“newuser”,为新增用户添加权限:
图中所示就是为“newuser”在“/”路径下设置了全部的配置、读、写权限,点击Set permission按钮即可。
再次返回用户列表后,newuser就具备了权限:
1.6 按照RabbitMQ的python客户端pika,可以参考官方示例或如下代码测试使用RabbitMQ收发消息:
消息发送端amqp_p.py:
import sys
import pika
params = pika.URLParameters('amqp://guest:guest@localhost:5672/%2F')
connection = pika.BlockingConnection(params)
channel = connection.channel()
channel.exchange_declare(
exchange='web_test',
exchange_type='direct',
passive=False,
durable=True,
auto_delete=False)
if len(sys.argv) != 1:
msg = sys.argv[1]
else:
msg = 'Hello RabbitMQ!'
pros = pika.BasicProperties(content_type='text/plain', delivery_mode=2)
channel.basic_publish(
exchange='web_test', routing_key='rout_test', body=msg, properties=pros)
connection.close()
消息接收端 amqp_c.py:
import pika
def on_message(channel,method_frame,header_frame,body):
channel.basic_ack(delivery_tag=method_frame.delivery_tag)
print('收到的消息内容为:',body)
params = pika.URLParameters('amqp://guest:guest@localhost:5672/%2F')
connection = pika.BlockingConnection(params)
channel = connection.channel()
channel.exchange_declare(exchange='web_test',exchange_type='direct',durable=True)
channel.queue_declare(queue='queue_test',auto_delete=True)
channel.queue_bind(queue='queue_test',exchange='web_test',routing_key='rout_test')
channel.basic_consume(consumer_callback=on_message,queue='queue_test')
try:
channel.start_consuming()
except KeyboardInterrupt as e:
channel.stop_consuming()
connection.close()
注意:代码中的%2F就是“/”的转义。
先启动一个终端,运行消费者amqp_c.py,运行后会等待消息。然后再启动一个终端运行amqp_p.py,启动时可以添加额外的参数,添加的参数就是要发送的消息否则就是代码中写死的Hello RabbitMQ!
发送端一旦消息发送出去就会结束运行。
接收端会一直处于运行状态等待接收消息,如果需要退出可以按下Ctrl + C。
2. Celery的使用
参考Celery的官方案例,根据本机的用户做了些微修改 celerydemo.py
from celery import Celery
app = Celery('celerydemo',broker='pyamqp://test:test@localhost:5672/%2F')
@app.task
def say(x,y):
print('hello celery')
return x + y
首先启动一个终端,输入命令行启动:
celery -A celerydemo worker -l info
启动后终端界面如下:
此时启动另一个终端,以交互的方式运行celerydemo模块中的say函数:
此时,在Windows系统中,运行celery的终端中马上会报错,错误信息为:
ValueError: not enough values to unpack (expected 3, got 0)
造成这个错误的原因是需要为celery配置一个--pool / -P参数。
如果安装了eventlet或gevent这样的并发库可以作为--pool / -P参数的值,如果没有或不想使用,则指定参数值为“solo”
celery -A celerydemo worker -P eventlet -l info
celery -A celerydemo worker -P solo -l info
此时另一个终端再次执行say.delay时,就可以在运行celery的终端中显示出结果。
但是如果想调用AsyncResult类型对象r的进一步信息时,都会产生错误:
产生错误的原因是我们没有给celery指定保存结果信息的backend。
修改celerydemo.py源代码,为celery指定backend:
from celery import Celery
app = Celery('celerydemo',backend='redis://localhost:6379/0',broker='pyamqp://test:test@localhost:5672/%2F')
@app.task
def say(x,y):
print('hello celery')
return x + y
再次启动后,终端中界面如下:
此时再次在另一个终端中操作AsyncResult对象就不会报错了:
以上就是在第一次使用Celery的时候遇到的一些问题,总结一下希望对大家能有所帮助。