python的flask框架里怎么起定时任务&执行异步任务

python的flask框架里怎么起定时任务&执行异步任务

在工作场景里,我一开始知道定时任务和异步,就是celery.后来起一个小项目,懒得装celery,才去找到了flask-apscheduler这个扩展.

比较下来flask-apscheduler肯定更小巧方便.

celery

介绍

中文文档:https://www.celerycn.io/

另一个:Celery中文文档

它是一个分布系统,用来处理批量的消息.

任务队列

任务队列一般用于线程或计算机之间分配工作的一种机制。

名词解释:

Broker:中间人

Worker:职程,其实就是做任务的东西

beat:如果你用celery做定时任务,需要用到beat

客户端向队列发送消息,Broker把消息传递给Worker,最后由Worker执行

我这边用的Broker时RabbitMQ

也就是说客户端有很多任务要执行,不能直接交给Worker来做,需要一个Broker在中间调节.

优点

主要还是灵活,它的自定义连接池序列化方式压缩方式日志记录方式任务调度生产者消费者中间人(Broker)等都可以自定义定义.

Broker

有RabbitMQ,Redis,Amazon SQS

我这边用的是RabbitMQ

安装RabbitMQ要注意,安装路径不能有中文,你的电脑,用户,起名千万不要起中文名.不然就会和我一样,重装.或者永远不装RabbitMQ.

还有就是安装RabbitMQ要装erlang,要注意好erlang和RabbitMQ的版本对应.

启动就是打开文件夹->sbin->server.bat就启动了

使用方法

当你需要异步执行一个任务时:

可以初始化一个tasks

app = Celery('tasks', broker='amqp://guest@localhost//')  # 指定broker为rabbitmq
@app.task()
def print_task(x, y):  # 一个任务
    print(x + y)

启动命令:(打在terminal)

celery -A tasks worker -l INFO
​
celery -A tasks worker -l INFO -P solo -c 2
# 这个的意思是启动tasks示例 打印info日志 -P solo是pool solo执行池指定为solo -c 2是2个进程
# -P / --pool prefork(默认使用)、solo、eventlet、gevent
# 参数
# -A / --app    要使用的应用程序实例
# -n / --hostname   设置自定义主机名
# -Q / --queues 指定一个消息队列,该进程只接受此队列的任务
# –max-tasks-per-child  配置工作单元子进程在被一个新进程取代之前可以执行的最大任务数量
# –max-memory-per-child 设置工作单元子进程被替换之前可以使用的最大内存
# -l / --loglevel   定义打印log的等级 DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL
# –autoscale    池的进程的最大数量和最小数量
# -c / --concurrency    同时处理任务的工作进程数量,默认值是系统上可用的cpu数量
# -B / --beat   定义运行celery打周期任务调度程序
# -h / --help   help!help!help!
# 也就是说这一行的意思是 启动tasks这个实例,打印info日志
# control + c可以退出

此时就可以异步执行print_task这个方法了,只需要

print_task.delay(x, y)
# 或者
print_task.apply_async([x, y])
delay和apply_async的应用差不多,是apply_async的简便版.
# .delay(_args, *_kwargs)等价于调用 .apply_async(args, kwargs)
task.delay(arg1, arg2, kwarg1='x', kwarg2='y')
# 等同于
task.apply_async(args=[arg1, arg2], kwargs={'kwarg1': 'x', 'kwarg2': 'y'})
# 但是delay不支持其他参数,apply_async支持很多
task.apply_async(countdown=10)  # 现在开始10s后执行
task.apply_async(eta=now + timedelta(seconds=10))  # 10s后 指明eta
task.apply_async(countdown=60, expires=120)  # 60s后, 120s后过期
task.apply_async(expires=now + timedelta(days=2))  # 指定2天后过期

定时任务

要启用beat

celery -A tasks beat 

代码:

@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
    # 每天早上7点00 执行print_task 参数为1, 2
    sender.add_periodic_task(crontab(hour="7", minute="0"), print_task.s(1, 2),
                             name='print_task')
# minute="*/5" 每五分钟

感受

用下来感觉功能非常全面,但是启动真的很麻烦.

我要先打开rabbitmq

再打开监听

再打开beat

再写好任务

如果定时任务要等待时间

如果是异步我要delay

而且要装一堆东西

所以我查到了下面这个

flask-apscheduler

安装

pip install flask-apscheduler

介绍

适配于Flask框架 是APScheduler扩展 支持flask配置类加载定时任务调度器配置和任务配置明细 提供内部restful风格API监控管理定时任务、认证机制、host白名单访问机制 高度与flask蓝图集成

"""add_job(func, trigger=None, args=None, kwargs=None, id=None, \
            name=None, misfire_grace_time=undefined, coalesce=undefined, \
            max_instances=undefined, next_run_time=undefined, \
            jobstore='default', executor='default', \
            replace_existing=False, **trigger_args)
​
        Adds the given job to the job list and wakes up the scheduler if it's already running.
​
        Any option that defaults to ``undefined`` will be replaced with the corresponding default
        value when the job is scheduled (which happens when the scheduler is started, or
        immediately if the scheduler is already running).
​
        The ``func`` argument can be given either as a callable object or a textual reference in
        the ``package.module:some.object`` format, where the first half (separated by ``:``) is an
        importable module and the second half is a reference to the callable object, relative to
        the module.
​
        The ``trigger`` argument can either be:
          #. the alias name of the trigger (e.g. ``date``, ``interval`` or ``cron``), in which case
            any extra keyword arguments to this method are passed on to the trigger's constructor
          #. an instance of a trigger class
​
        :param func: callable (or a textual reference to one) to run at the given time
        :param str|apscheduler.triggers.base.BaseTrigger trigger: trigger that determines when
            ``func`` is called
        :param list|tuple args: list of positional arguments to call func with
        :param dict kwargs: dict of keyword arguments to call func with
        :param str|unicode id: explicit identifier for the job (for modifying it later)
        :param str|unicode name: textual description of the job
        :param int misfire_grace_time: seconds after the designated runtime that the job is still
            allowed to be run (or ``None`` to allow the job to run no matter how late it is)
        :param bool coalesce: run once instead of many times if the scheduler determines that the
            job should be run more than once in succession
        :param int max_instances: maximum number of concurrently running instances allowed for this
            job
        :param datetime next_run_time: when to first run the job, regardless of the trigger (pass
            ``None`` to add the job as paused)
        :param str|unicode jobstore: alias of the job store to store the job in
        :param str|unicode executor: alias of the executor to run the job with
        :param bool replace_existing: ``True`` to replace an existing job with the same ``id``
            (but retain the number of runs from the existing one)
        :rtype: Job
        """
    """
将给定的任务添加到任务列表中,并在调度程序已在运行时唤醒它。
当调度作业时,任何默认为“未定义”的选项都将替换为相应的默认值(当调度程序启动时,或当调度程序已在运行时立即发生)。
“func”参数可以作为中的可调用对象或文本引用给出
`package.module:some.object`格式,其中前半部分(用`:``分隔)是可导入模块,后半部分是对可调用对象的引用,相对于模块。
“触发器”参数可以是:
#.触发器的别名(例如“date”、“interval”或“cron”),在这种情况下
该方法的任何额外关键字参数都会传递给触发器的构造函数
#.触发器类的实例
:param func:可调用(或对函数的文本引用)以在给定时间运行
:param str | apscheduler.triggers.base.BaseTrigger trigger:确定何时的触发器
``调用了func ``
:param list | tuple args:用于调用func的位置参数列表
:param dict kwargs:用于调用func的关键字实参的dict
:param str | unicode id:作业的显式标识符(用于以后修改)
:param str | unicode name:作业的文本描述
:param int miscelle_grace_time:指定运行时后作业仍然存在的秒数 允许运行(或“无”以允许作业无论多晚都能运行)
:param bool coalize:如果调度程序确定作业应连续运行多次
:param int max_instances:允许同时运行的最大实例数
工作
:param datetime next_run_time:第一次运行作业的时间,与触发器无关(通过
``无``以将作业添加为暂停)
:param str | unicode jobstore:用于存储作业的作业存储的别名
:param str | unicode executor:用于运行作业的执行器的别名
:param bool replace_existing:`True``用相同的``id替换现有作业``
(但保留现有执行次数)
​
:r类型:作业"""
# func 要执行的函数
# trigger 触发方式 (1)date: 特定的时间点触发(2)interval: 固定时间间隔触发(3)cron: 在特定时间周期性地触发
# args 参数 tuple
# kwargs  参数 dict
# id  唯一值 unicode
# name  名字
# misfire_grace_time 延迟执行时间 int 空的话代表永久 例如Job的计划执行时间是21:00:00,但因服务重启或其他原因导致21:00:31才执行,如果设置40,则该job会继续执行 
# coalesce Job是否合并执行 例如scheduler停止20s后重新启动,而job的触发器设置为5s执行一次,因此此job错过了4个执行时间,如果设置为是,则会合并到一次执行,否则会逐个执行 bool
# max_instances 此job允许同时运行的最大实例数 int
# next_run_time 什么时候第一次运行 不考虑trigger datetime
# jobstore 任务存储 str|unicode 存储被调度的任务,默认的任务存储是保存在内存中。同时支持任务存储在数据库中,一个任务的数据将在保存到持久化作业存储时被序列化,并在加载时被反序列化。
# executor 执行器 str|unicode job创建时设置执行器的名字,根据执行器的名字发送给scheduler获取到执行此job的执行器,执行job指定的函数
# replace_existing true:替换已经有的同样id的作业 bool

使用

from apscheduler.schedulers.background import BackgroundScheduler
​
def my_task():
    pass
​
scheduler = BackgroundScheduler()  # 初始化
scheduler.add_job(my_task, trigger='interval', id='my_task', minutes=1)  # 意思就是一分钟执行一次my_task
scheduler.add_job(my_task, trigger='interval', id='my_task', minutes=1, start_date='2024-01-01 00:00:00' , end_date='2025-01-01 00:00:00')  # 意思是在2024-01-01 00:00:00 ~ 2025-01-01 00:00:00时间内 每一分钟执行一次my_task
scheduler.start()

感受

方便 装个包就行 但是功能不齐全 没有测过大的并发量下的执行情况

一开始只是为了一个小项目

还有一个注意事项,如果debug=True的话,任务会执行两次的

  • 27
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
动态实时大屏监管系统是基于Echarts和Python Flask开发的。Echarts是一款功能强大的JavaScript图表库,能够提供丰富的数据可视化效果。而Python Flask是一款轻量级的Web框架,可以方便地搭建Web应用。 在这个系统中,我们使用了Echarts来展示各种图表,如饼图、折线图、柱状图等,以便实时监管和展示数据。Python Flask则负责处理数据的获取和处理。 通过Flask框架,我们可以设置路由,处理请求。系统可以实现数据的动态获取和实时更新。例如,可以通过定时任务或者异步请求来定时获取数据,并实时更新到Echarts图表中。同时,也可以根据需要使用数据库来存储和管理数据。 系统的源码主要包括两部分:前端代码和后端代码。前端代码主要是使用HTML、CSS和JavaScript编写,主要负责Echarts的初始化和配置。后端代码使用Python编写,主要使用了Flask框架,负责处理数据请求和数据的处理,还包括与数据库的交互逻辑。 此外,系统还可以进行权限管理和用户登录验证等功能。可以根据不同用户的权限,显示不同的监管数据和图表。用户登录后,通过验证可以进入系统,根据业务需求进行数据展示和管理。 总之,基于Echarts和Python Flask的动态实时大屏监管系统能够实现实时监管和展示各种图表。通过优雅的可视化方式,能够更好地把握数据的动态变化和趋势,为决策提供可靠依据。同时,系统还可以根据具体业务需求进行功能扩展和定制化开发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易安30

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值