异步方案——RabbitMQ+Celery

异步方案——RabbitMQ+Celery

1、RabbitMQ介绍和使用

1.1、生产者消费者设计模式

最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联。

生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。

1.2. RabbitMQ介绍

  • 消息队列是消息在传输的过程中保存消息的容器。

  • 现在主流消息队列有:RabbitMQ、ActiveMQ、Kafka等等。

  • RabbitMQ和ActiveMQ比较

    系统吞吐量:RabbitMQ好于ActiveMQ
    持久化消息:RabbitMQ和ActiveMQ都支持
    高并发和可靠性:RabbitMQ好于ActiveMQ

  • RabbitMQ和Kafka:

    系统吞吐量:RabbitMQ弱于Kafka
    可靠性和稳定性:RabbitMQ好于Kafka比较
    设计初衷:Kafka是处理日志的,是日志系统,所以并没有具备一个成熟MQ应该具备的特性。

1.3、安装RabbitMQ(centos7)

单机部署

1、创建erlang.repo库

curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash

2、安装erlang

yum install erlang

3、创建rabbitmq-server.repo库

curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash

4、安装rabbitmq-server

yum install rabbitmq-server

5、设置开机启动

chkconfig rabbitmq-server on

6、启动rabbitmq节点

service rabbitmq-server start

其他命令和用法。。

1.4、Python访问RabbitMQ

RabbitMQ提供默认的administrator账户。
用户名和密码:guest、guest
协议:amqp
地址:localhost
端口:5672
查看队列中的消息:sudo rabbitctl list_queues

Python3虚拟环境下,安装pika

pip install pika

生产者代码:rabbitmq_producer.py

import pika

# 链接到RabbitMQ服务器
credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))

#创建频道
channel = connection.channel()
# 声明消息队列
channel.queue_declare(queue='zxc')

# routing_key是队列名 body是要插入的内容
channel.basic_publish(exchange='', routing_key='zxc', body='Hello RabbitMQ!')
print("开始向 'zxc' 队列中发布消息 'Hello RabbitMQ!'")
# 关闭链接
connection.close()

消费者代码:rabbitmq_customer.py

import pika

# 链接到rabbitmq服务器
credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))
# 创建频道,声明消息队列
channel = connection.channel()
channel.queue_declare(queue='zxc')
# 定义接受消息的回调函数
def callback(ch, method, properties, body):
    print(body)
# 告诉RabbitMQ使用callback来接收信息
channel.basic_consume(callback, queue='zxc', no_ack=True)
# 开始接收信息
channel.start_consuming()

其他用法

2、Celery介绍和使用

2.1、Celery介绍:

一个简单、灵活且可靠、处理大量消息的分布式系统,可以在一台或者多台机器上运行。
单个 Celery 进程每分钟可处理数以百万计的任务。

通过消息进行通信,使用消息队列(broker)在客户端和消费者之间进行协调。

2.2、安装Celery:

pip install -U Celery

2.2、 创建Celery实例并加载配置

celery_tasks.main.py

# -*- coding: utf-8 -*-

from celery import Celery


# 创建celery对象
app = Celery('my_celery')

# 加载配置
app.config_from_object('celery_tasks.config')

# 加载可用的任务
app.autodiscover_tasks([
    'celery_tasks.my_task',
])

celery_tasks.config.py

# -*- coding: utf-8 -*-


# 指定rabbitmq作为celery的队列,可以改成redis等
broker_url = 'amqp://guest:guest@localhost:5672'

2.3、定义异步任务

定义任务:celery_tasks.my_task.tasks.py

# -*- coding: utf-8 -*-

import time
import requests
from celery_tasks.main import app


@app.task(bind=True, name='spider_task', retry_backoff=3)
def spider_task(self, url):
    # 将耗时的代码封装在一个方法中
    ret = requests.get(url=url).status_code
    if ret != 200:
        raise self.retry(exc=Exception('异步失败'), max_retries=3)

    time.sleep(1)  # 测试耗时
    return ret

2.4、启动Celery服务

celery -A celery_tasks.main worker --pool=solo -l info

-A指对应的应用程序, 其参数是项目中 Celery实例的位置。

worker指这里要启动的worker。

-l指日志等级,比如info等级。

celery最新版本需要添加:–pool=solo。

3、测试异步爬虫请求

celery_tasks.usage.py

# -*- coding: utf-8 -*-


from celery_tasks.my_task.tasks import spider_task

url = 'https://www.baidu.com/'

for i in range(10):
    print(spider_task.delay(url))
    

运行usage.py,立即返回全部任务id,同时celery窗口开始运行耗时的任务,完美。

4、扩展

4.1、celery协程工作模式

默认是进程池方式,进程数以当前机器的CPU核数为参考,每个CPU开四个进程。

如何自己指定进程数:celery worker -A proj --concurrency=4

如何改变进程池方式为协程方式:celery worker -A proj --concurrency=1000 -P eventlet -c 1000

# 安装eventlet模块
$ pip install eventlet

# 启用 Eventlet 池
$ celery -A celery_tasks.main worker -l info -P eventlet -c 1000

4.2、docker安装RabbitMQ

下载RabbitMQ最小镜像:

docker pull rabbitmq:alpine

启动RabbitMQ容器:

docker run -d --hostname my-rabbit -p 5672:5672 --name some-rabbit rabbitmq:alpine

记得防火墙和安全组开放5672端口。

5、参考

https://github.com/docker-library/docs/tree/master/rabbitmq

https://cloud.tencent.com/developer/article/1447179

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值