本文首发于公众号: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. elasticsearch 官方优化建议

    1.一般建议   a.不要返回过大的结果集.这个建议对一般数据库都是适用的,如果要获取大量结果,可以使用search_after api,或者scroll (新版本中已经不推荐).   b.避免大的文 ...

  2. C++ 标准库 sort() / stable_sort() / partial_sort() 对比

    C++ STL标准库中提供了多个用于排序的Sort函数,常用的包括有sort() / stable_sort() / partial_sort(),具体的函数用法如下表所示: 函数 用法 std::s ...

  3. DevOps infra | 互联网、软件公司基础设施建设(基建)哪家强?

    国内公司普遍不注重基础设施建设,这也是可以理解的.吃饭都吃不饱,就别提什么荤素搭配,两菜一汤了.但也不能全说是这样,还是有很多公司投入大量的人力物力去做好公司的基建,比如很多阿里和美团的小伙伴对公司的 ...

  4. Kubernetes客户端认证(二)—— 基于ServiceAccount的JWTToken认证

    1.概述 在 Kubernetes 官方手册中给出了 "用户" 的概念,Kubernetes 集群中存在的用户包括 "普通用户" 与 "Service ...

  5. 颜值即正义,献礼就业季,打造多颜色多字体双飞翼布局技术简历模版(Resume)

    一年好景君须记,最是橙黄橘绿时.金三银四,秣马厉兵,没有一个好看的简历模板怎么行?无论是网上随便下载还是花钱买,都是一律千篇的老式模版,平平无奇,味同嚼蜡,没错,蜡都要沿着嘴角流下来了.本次我们基于H ...

  6. Generative Pre-trained Transformer(GPT)模型技术初探

    一.Transformer模型 2017年,Google在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取 ...

  7. OpenHarmony SystemUI开发记录

    背景介绍 最近学习OpenHarmony应用开发, SDK版本是3.2.9.2 Beta4,IDE版本是3.1.0.200.参考官方文档,做了个Demo应用,调试.运行非常顺利.启动应用后,状态栏和导 ...

  8. Django框架简单搭建增删改查页面 Django请求生命周期流程图

    目录 Django框架简单搭建增删改查页面 一.前期的配置文件以及连接MySQL的基本准备 二.在数据库中准备好数据 三.将MySQL的数据展示到页面(简单认识HTML模板语法 for循环) 在Dja ...

  9. 武装你的WEBAPI-OData Versioning

    本文属于OData系列 目录 武装你的WEBAPI-OData入门 武装你的WEBAPI-OData便捷查询 武装你的WEBAPI-OData分页查询 武装你的WEBAPI-OData资源更新Delt ...

  10. 2020-09-11:Hive的优化策略有哪些?

    福哥答案2020-09-11: [Hive调优及优化的12种方式](https://zhuanlan.zhihu.com/p/80718835?utm_source=qq)1.请慎重使用COUNT(D ...