<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Celery &#8211; 李辉 / Grey Li</title>
	<atom:link href="https://greyli.com/tag/celery/feed/" rel="self" type="application/rss+xml" />
	<link>https://greyli.com</link>
	<description>一个编程和写作爱好者的在线记事本</description>
	<lastBuildDate>Thu, 06 Nov 2025 11:36:11 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.26</generator>

<image>
	<url>https://greyli.com/wp-content/uploads/2025/03/avatar-500-compressed-144x144.jpg</url>
	<title>Celery &#8211; 李辉 / Grey Li</title>
	<link>https://greyli.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>在 Flask 项目中使用 Celery（with 工厂模式 or not）</title>
		<link>https://greyli.com/use-celery-with-flask-factory-or-not/</link>
		<comments>https://greyli.com/use-celery-with-flask-factory-or-not/#comments</comments>
		<pubDate>Wed, 24 Apr 2019 10:58:27 +0000</pubDate>
		<dc:creator><![CDATA[李辉]]></dc:creator>
				<category><![CDATA[计算机与编程]]></category>
		<category><![CDATA[Celery]]></category>
		<category><![CDATA[Flask]]></category>

		<guid isPermaLink="false">http://greyli.com/?p=2428</guid>
		<description><![CDATA[本文隶属于《Flask Web 开发实战》番外系列。这篇文章会介绍如何在 Flask 项目中集成 Celery [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>
	本文隶属于<a href="http://greyli.com/flask-web-appendix/" spellcheck="false">《Flask Web 开发实战》番外</a>系列。这篇文章会介绍如何在 Flask 项目中集成 Celery。
</p>
<h2>
	创建 Celery 程序<br />
</h2>
<p>
	第一步是创建一个 Celery 程序实例。因为 Flask 程序实例通常会命名为 app，为了避免冲突，我们一般会把 Celery 实例命名为 celery 或 celery_app：
</p>
<pre>
<code>from celery import Celery

celery = Celery(__name__, broker=&#39;pyamqp://guest@localhost//&#39;)

@celery.task
def add(x, y):
    return x + y</code></pre>
<h2>
	组织和加载配置<br />
</h2>
<p>
	大多数教程，包括目前的 Flask 文档里都会介绍用下面的方式加载配置：
</p>
<pre>
<code>celery.conf.update(app.config)  # 这里的 app 是 Flask 程序实例</code></pre>
<p>
	也就是把 Celery 配置和 Flask 配置写在一起，然后从 Flask 程序实例的配置字典里更新配置。
</p>
<p>
	但问题是，Celery 从 4.0 开始启用新的小写配置名，某些配置被新的名称替换。虽然旧的大写配置仍然支持，但如果你打算使用小写配置名，或是打算在未来进行迁移，这里的配置加载方式就会失效，因为 Flask 在从文件或对象导入配置时只会导入大写形式的配置变量。
</p>
<p>
	因此，我建议将 Celery 配置写在单独的文件里，不要和 Flask 配置混在一起。按照 Celery 文档的示例，你可以在当前目录创建一个&nbsp;<a href="http://celeryconfig.py/">celeryconfig.py</a>&nbsp;文件（或是其他名字）保存配置：
</p>
<pre>
<code>broker_url = &#39;pyamqp://&#39;
result_backend = &#39;rpc://&#39;

task_serializer = &#39;json&#39;
result_serializer = &#39;json&#39;
accept_content = ['json']
timezone = &#39;Europe/Oslo&#39;
enable_utc = True</code></pre>
<p>
	然后使用下面的方法加载配置（使用其他模块名，或是在其他路径时，记得修改传入的字符串）：
</p>
<pre>
<code>celery.config_from_object(&#39;celeryconfig&#39;)</code></pre>
<p>
	如果需要在创建 Celery 实例时传入 broker 和 backend 配置，可以直接写出或是从配置模块中导入：
</p>
<pre>
<code>from celeryconfig import broker_url

celery = Celery(__name__, broker=broker_url)</code></pre>
<h2>
	在 Flask 程序中初始化 Celery<br />
</h2>
<p>
	你可以单独创建 Celery 程序，但我们通常会需要为它添加 Flask 程序上下文支持，因为有时候你的 Celery 任务函数会用到依赖于 Flask 程序上下文的某些变量。
</p>
<p>
	下面我们为 Celery 创建了一个工厂函数，在工厂函数中创建 Celery 实例，加载配置，并实现 Flask 程序上下文支持：
</p>
<pre>
<code>from flask import Flask
from celery import Celery

from celeryconfig import broker_url


def make_celery(app):
    celery = Celery(__name__, broker=broker_url)
    celery.config_from_object(&#39;celeryconfig&#39;)

    class ContextTask(celery.Task):
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)

    celery.Task = ContextTask
    return celery

app = Flask(__name__)

celery = make_celery(app)</code></pre>
<p>
	在定义 Celery 任务的模块里，比如 tasks.py，你可以导入这个 Celery 程序实例：
</p>
<pre>
<code>from app import celery

@celery.task
def add(x, y):
    return x + y</code></pre>
<h2>
	在使用工厂函数的 Flask 程序中初始化 Celery<br />
</h2>
<p>
	当 Flask 程序也使用工厂函数创建时，我们可以全局创建 Celery 程序实例，然后在创建 Flask 程序实例的工厂函数里更新 Celery 程序配置并进行上下文设置：
</p>
<pre>
<code>from flask import Flask
from celery import Celery

from celeryconfig import broker_url
 
celery = Celery(__name__, broker=broker_url)
 

def create_app():
    app = Flask(__name__)
 
    register_celery(app)
    return app
 

def register_celery(app):
    celery.config_from_object(&#39;celeryconfig&#39;)
 
    class ContextTask(celery.Task):
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)
 
    celery.Task = ContextTask</code></pre>
<p>
	同样直接导入 Celery 实例并创建任务：
</p>
<pre>
<code>from app import celery

@celery.task
def add(x, y):
    return x + y</code></pre>
<p>
	这本来是一个完整的 Celery 入门教程，但因为去年的一次硬盘损坏，对应的示例程序弄丢了，暂时没有毅力重写一遍，所以这篇文章只抽取了其中和 Flask 相关的内容。
</p>
<p>
	因为距离初稿写作的时间已经过去半年多，Celery 的最新版本也已经是 4.3.0，如果文中有什么疏漏，或是有更好的实现方式，欢迎评论指出。</p>
]]></content:encoded>
			<wfw:commentRss>https://greyli.com/use-celery-with-flask-factory-or-not/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
