定时修正统计数据1------apscheduler独立运行,以阻塞方式运行

新建/scheduler/包路径

新建/scheduler/main.py文件

import sys
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'common'))
sys.path.insert(0, os.path.join(BASE_DIR))

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.executors.pool import ProcessPoolExecutor

# 创建一个apscheduler调度器对象

# 配置调度器对象使用的 任务存储后端  执行器(进程、线程)

executors = {
    # 表示默认到了时间,该执行的定时任务都是放到进程池中的一个子进程执行
    # 3表示进程池中最多有3个进程,也就说 在同一时刻,最多 有3个进程同时执行
    'default': ProcessPoolExecutor(3)
}

# Blocking 阻塞的调度
scheduler = BlockingScheduler(executors=executors)

import common

# 添加定时任务

# 在每天的凌晨3点执行
from statistic import fix_statistics
scheduler.add_job(fix_statistics, 'cron', hour=3)

# 测试使用这个触发时间,在scheduler启动的使用执行一次定时任务
# scheduler.add_job(fix_statistics, 'date')


# 启动scheduler
if __name__ == '__main__':
    # start()会阻塞当前文件退出
    scheduler.start()

新建/scheduler/statistic.py文件

from sqlalchemy import func
from flask import current_app

from models.news import Article
from models import db
from cache import statistic as cache_statistic
from common import flask_app


def __fix_statistics(cls):
    # 进行数据库查询
    with flask_app.app_context():
        ret = cls.db_query()

        # 将数据库查询结果设置到redis中
        cls.reset(ret)


def fix_statistics():
    """
    修正redis中存储的统计数据 定时任务
    :return:
    """
    # 查询数据库得到统计数据
    # class UserArticlesCountStorage(CountStorageBase):
    #     """
    #     用户文章数量
    #     """
    #     key = 'count:user:arts'   zset  4,1

    # sql
    # select user_id, count(article_id)  from news_article_basic where status=2 group by user_id
    # ret = db.session.query(Article.user_id, func.count(Article.id))\
    #         .filter(Article.status == Article.STATUS.APPROVED)\
    #         .group_by(Article.user_id).all()

    # ret -> [
    # ( 1, 46141),
    # (2, 46357 ),
    # (3 ,46187)
    # ]

    # # 设置redis的存储记录
    # pl = current_app.redis_master.pipeline()
    # pl.delete('count:user:arts')
    #
    # # zadd(key, score1, val1, score2, val2, ...)
    # for user_id, count in ret:
    #     pl.zadd('count:user:arts', count, user_id)
    #
    # pl.execute()

    __fix_statistics(cache_statistic.UserArticleCountStorage)

    __fix_statistics(cache_statistic.UserFollowingCountStorage)

    __fix_statistics(cache_statistic.ArticleCollectingCountStorage)

    __fix_statistics(cache_statistic.UserArticleCollectingCountStorage)

新建/scheduler/comment.py文件---->防止文件statistic.py与main.py文件循环调用

# 创建定时任务中需要使用到的数据库对象和redis对象
# 可以通过调用create_app 方法,创建flask app的时候,此方法会连带初始化数据库db对象和redis对象
from toutiao import create_app
from settings.default import DefaultConfig

flask_app = create_app(DefaultConfig, enable_config_file=True)

进入服务器系统运行文件执行

python main.py
posted @ 2020-09-03 04:03  sewen  Views(366)  Comments(0)    收藏  举报