本文首发于公众号:Hunter后端

原文链接:celery笔记六之worker介绍

前面我们介绍过 celery 的理想的设计方式是几个 worker 处理特定的任务队列的数据,这样可以避免任务在队列中的积压。

这一篇笔记我们介绍一下如何使用 worker 提高系统中任务的处理效率。

  1. worker启动
  2. worker与队列
  3. worker检测
  4. 其他worker命令

1、worker 启动

前面介绍过 worker 的启动方式,在 celery 配置文件的上一级目录运行下面的命令:

celery -A hunter worker -l INFO

其中,-l 表示日志等级,相当于是 --loglevel=INFO

celery -A hunter worker --loglevel=INFO

指定worker的hostname

celery -A hunter worker -l INFO -n worker1@%h

其中,%h 表示主机名,包含域名在内,%n 表示仅包含主机名,%d 表示仅包含域名。

以下是示例:

变量 示例 结果
%h worker1@%h worker1@george.example.com
%n worker1@%n worker1@george
%d worker1@%d worker1@example.com

指定日志文件地址

logfile 参数可以指定日志文件地址:

celery -A hunter worker --loglevel=INFO --logfile=/Users/hunter/python/celery_log/celery.log

杀死 worker 进程

我们可以通过获取 worker 的进程 id 来杀死这些进程:

ps aux | grep 'celery -A hunter' | awk '{print $2}' |xargs sudo kill -9

并发处理

一般来说,当我们直接启动 worker 的时候,会默认同时起好几个 worker 进程。

如果不指定 worker 的数量,worker 的进程会默认是所在机器的 CPU 的数量。

我们也可以通过 concurrency 参数来指定启动 worker 的进程数。

比如说,我们想启动三个 worker 的进程,可以如下指定:

celery -A hunter worker --concurrency=3 -l INFO

--concurrency 也可以简写成 -c:

celery -A hunter worker -c 3 -l INFO

这样,我们在启动的命令行里输入下面的参数就可以看到启动了三个 worker 的进程:

ps aux |grep 'celery -A hunter'

这里有一个关于 worker 进程数启动多少的问题,是不是我们的 worker 启动的越多,我们的定时任务和延时任务就会执行得越快呢?

并不是,有实验证明 worker 的数量启动得越多,对于 task 处理的性能有可能还会起到一个反向作用,这里不作展开讨论,我们可以设置 CPU 的数量即可。

当然,你也可以根据 worker 处理任务的情况,基于 application,基于工作负载,任务运行时间等试验出一个最佳的数量。

2、worker与队列

消费指定队列的task

我们可以在运行 worker 的时候指定 worker 只消费特定队列的 task,这个特定队列,可以是一个,也可以是多个,用逗号分隔开。

指定的方式如下:

celery -A hunter worker -l INFO -Q queue_1,queue_2

列出所有活跃的queues

下面的命令可以列出所有系统活跃的队列信息:

celery -A hunter inspect active_queues

假设目前我们相关配置如下:

app.conf.task_queues = (
Queue('default_queue',),
Queue('queue_1'),
Queue('queue_2'),
) app.conf.task_routes = {
'blog.tasks.add': {
'queue': 'queue_1',
},
'blog.tasks.minus': {
'queue': 'queue_2',
},
}

我们这样启动worker:

celery -A hunter worker -l INFO -c 3 -n worker1@%h

然后运行上面的查看队列命令:

celery -A hunter inspect active_queues

可以看到如下输出:

->  worker1@localhost: OK
* {'name': 'default_queue', 'exchange': {...}, 'routing_key': 'default_queue', ...}
* {'name': 'queue_1', 'exchange': {...}, 'routing_key': 'default_queue', ...}
* {'name': 'queue_2', 'exchange': {...}, 'routing_key': 'default_queue', ...} 1 node online.

其中,输出结果最上面的 worker1@localhost 就是我们启动 worker 通过 -n 指定的 hostnam,可以通过这个来指定 worker。

我们可以指定 worker 输出对应的队列数据:

celery -A hunter inspect active_queues -d worker1@localhost

除了命令行,我们也可以在交互界面来获取这些数据:

# 获取所有的队列信息
from hunter.celery import app
app.control.inspect().active_queues() # 获取指定 worker 的队列信息
app.control.inspect(['worker1@localhost']).active_queues()

3、worker 的检测

app.control.inspect() 函数可以检测正在运行的 worker 信息,我们可以用下面的命令来操作:

from hunter.celery import app

i = app.control.inspect()

这个操作是获取所有节点,我们也可以指定单个或者多个节点检测:

# 输入数组参数,表示获取多个节点worker信息
i = app.control.inspect(['worker1@localhost', 'worker2@localhost']) # 输入单个worker名,指定获取worker信息
i = app.control.inspect('worker1@localhost')

获取已经注册的task列表

用到前面的 app.control.inspect() 函数和其下的 registered() 函数

i.registered()

# 输出结果为 worker 及其下的 task name
# 输出示例为 {'worker1@localhost': ['blog.tasks.add', 'blog.tasks.minus', 'polls.tasks.multi']}

输出的格式是一个 dict,worker 的名称为 key,task 列表为 value

正在执行的 task

active() 用于获取正在执行的 task 函数

i.active()

# 输出 worker 正在执行的 task
# 输出示例为 {'worker1@localhost': [{'id': 'xxx', 'name': 'blog.tasks.add', 'args': [3, 4], 'hostname': 'worker1@localhost', 'time_start': 1659450162.58197, ..., 'worker_pid': 41167}

输出的结果也是一个 dict,每个 worker 下有 n 个正在 worker 中执行的 task 信息,这个 n 的最大数量取决于前面我们启动 worker 时的 --concurrency 参数。

在其中的 task 信息里包含 task_id,task_name,和输入的参数,开始时间,worker name 等。

即将运行的 task

比如我们运行 add 延时任务,定时在 20s 之后运行:

add.apply_async((1, 1), countdown=20)

返回的结果每个 worker 下有一个任务列表,每个列表存有任务的信息:

i.scheduled()

# 输出信息如下
# {'worker1@localhost': [{'eta': '2022-08-02T22:56:49.503517+08:00', 'priority': 6, 'request': {'id': '23080c03-a906-4cc1-9ab1-f27890c58adb', 'name': 'blog.tasks.add', 'args': [1, 1], 'kwargs': {}, 'type': 'blog.tasks.add', 'hostname': 'worker1@localhost', 'time_start': None, 'acknowledged': False, 'delivery_info': {...}}]}

queue队列中等待的 task

如果我们有任务在 queue 中积压,我们可以使用:

i.reserved()

来获取队列中等待的 task 列表

4、其他 worker 命令

ping-pong

检测 worker 还活着的 worker

使用 ping() 函数,可以得到 pong 字符串的回复表明该 worker 是存活的。

from hunter.celery import app

app.control.ping(timeout=0.5)

# [{'worker1@localhost': {'ok': 'pong'}}]

我们也可以指定 worker 来操作:

app.control.ping(['worker1@localhost'])

如果你了解 redis 的存活检测操作的话,应该知道在 redis-cli 里也可以执行这个 ping-pong 的一来一回的检测操作。

如果想获取更多后端相关文章,可扫码关注阅读:

celery笔记六之worker介绍的更多相关文章

  1. Spring Boot笔记六:Thymeleaf介绍

    目录 什么是thymeleaf? 创建最简单的thymeleaf thymeleaf语法 什么是thymeleaf? thymeleaf是一个模板引擎,是用来在Spring Boot中代替JSP的 引 ...

  2. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  3. Nodejs学习笔记(十六)—Pomelo介绍&入门

    前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...

  4. Django笔记六之外键ForeignKey介绍

    这一篇笔记介绍 Django 系统 model 的外键处理,ForeignKey 以及相应的处理方法. 这是一种一对多的字段类型,表示两张表之间的关联关系. 本篇笔记的目录如下: on_delete ...

  5. Celery笔记

    异步任务神器 Celery 简明笔记 2016/12/19 · 工具与框架 · Celery, 异步 原文出处: FunHacks    在程序的运行过程中,我们经常会碰到一些耗时耗资源的操作,为了避 ...

  6. 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:/ ...

  7. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  8. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  10. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

随机推荐

  1. EF Core从TPH迁移到TPT

    Intro EF Core支持多种方式处理具有继承关系的表,现在支持TPH.TPC(EF Core 7).TPT,具体的实现方式可以参考官方文档和这篇文章. 大致总结一下不同的方式的区别: TPH:所 ...

  2. [Linux]ln:软链接与硬链接

    1 硬链接与软链接的[语法] 软链接:ln -s 源文件 目标文件 硬链接:ln 源文件 目标文件 [-s : symbolic,符号/代号] 2 软链接/硬链接的[比喻] / (编辑)同步性 [ro ...

  3. JUC(五)Callable

    Callable接口 创建线程的几种方式 继承Thread类 实现Runnable接口 通过Callable接口 线程池 使用Runnable接口无法获取到线程返回的结果,因此在jdk1.5后java ...

  4. 基于sanic和爬虫创建的代理ip池

    搭建免费的代理ip池 需要解决的问题: 使用什么方式存储ip 文件存储 缺点: 打开文件修改文件操作较麻烦 mysql 缺点: 查询速度较慢 mongodb 缺点: 查询速度较慢. 没有查重功能 re ...

  5. ChatCLM部署随笔

    ChatCLM 博客 ChatGLM Github ChatGLM-webui 介绍 ChatGLM-6B 是一个开源的.支持中英双语的对话语言模型,基于 General Language Model ...

  6. 【机器学习与深度学习理论要点】20. 什么是激活函数,为什么要用激活函数,常见的激活函数和特点,softmax函数

    1)什么是激活函数,为什么要用激活函数? 激活函数,指神经网络中将输入信号的总和转换为输出信号的函数,激活函数将多层感知机输出转换为非线性,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应 ...

  7. 2022-10-05:在一个 n x n 的整数矩阵 grid 中, 每一个方格的值 grid[i][j] 表示位置 (i, j) 的平台高度。 当开始下雨时,在时间为 t 时,水池中的水位为 t 。

    2022-10-05:在一个 n x n 的整数矩阵 grid 中, 每一个方格的值 grid[i][j] 表示位置 (i, j) 的平台高度. 当开始下雨时,在时间为 t 时,水池中的水位为 t . ...

  8. 2021-10-22:颠倒二进制位。颠倒给定的 32 位无符号整数的二进制位。提示:请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不

    2021-10-22:颠倒二进制位.颠倒给定的 32 位无符号整数的二进制位.提示:请注意,在某些语言(如 Java)中,没有无符号整数类型.在这种情况下,输入和输出都将被指定为有符号整数类型,并且不 ...

  9. vue cli3 整合Cesium,处理build 时内存溢出问题

    一直使用cesium,但是都是使用script直接引入的,但是在将其放置在增加路由的子页面中中时会出现一个问题,刷新后提示cesium is undefined 看直接引入cesium.js < ...

  10. 前后端分离架构下使用 Sa-Token 完成登录认证

    一.架构分析 目前绝大多数系统都已经采用 "前后端分离" 架构来设计了,传统的Session模式鉴权也不再适合这种架构(或者需要额外写很多的代码来专门适配). Sa-Token 是 ...