ubuntu

ubuntu如何实现分布式定时任务

小樊
42
2025-06-25 05:19:35
栏目: 智能运维

在Ubuntu上实现分布式定时任务,通常可以使用以下几种方法:

  1. 使用Cron结合分布式锁

    • 在每个节点上设置Cron任务。
    • 使用分布式锁(如Redis、etcd或Zookeeper)来确保同一时间只有一个节点执行任务。
  2. 使用Celery

    • Celery是一个分布式任务队列,支持定时任务(通过Celery Beat)。
    • 配置多个Celery worker节点来处理任务。
    • 使用Redis或RabbitMQ作为消息代理。
  3. 使用Apache Airflow

    • Airflow是一个工作流调度平台,可以定义复杂的任务依赖关系。
    • 支持分布式执行,可以在多个节点上运行Executor(如CeleryExecutor、KubernetesExecutor等)。
    • 配置Airflow Scheduler和Webserver在不同的节点上。
  4. 使用Kubernetes CronJobs

    • 如果你在Kubernetes集群中运行应用,可以使用Kubernetes的CronJob资源来调度定时任务。
    • Kubernetes会自动管理任务的分布式执行。

下面是一个简单的示例,展示如何使用Cron结合Redis分布式锁来实现分布式定时任务:

安装依赖

首先,安装所需的软件包:

sudo apt-get update
sudo apt-get install python3-pip redis-server
pip3 install redis

编写Python脚本

创建一个Python脚本distributed_cron.py,内容如下:

import time
import redis
from datetime import datetime

# 连接到Redis服务器
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)

def acquire_lock(lock_name, acquire_timeout=10):
    identifier = str(uuid.uuid4())
    end = time.time() + acquire_timeout
    while time.time() < end:
        if redis_client.setnx(lock_name, identifier):
            return identifier
        time.sleep(0.001)
    return False

def release_lock(lock_name, identifier):
    with redis_client.pipeline() as pipe:
        while True:
            try:
                pipe.watch(lock_name)
                if pipe.get(lock_name) == identifier:
                    pipe.multi()
                    pipe.delete(lock_name)
                    pipe.execute()
                    return True
                pipe.unwatch()
                break
            except redis.WatchError:
                pass
    return False

def task():
    print(f"Task executed at {datetime.now()}")

def main():
    lock_name = "distributed_cron_lock"
    identifier = acquire_lock(lock_name)
    if identifier:
        try:
            task()
        finally:
            release_lock(lock_name, identifier)
    else:
        print("Failed to acquire lock")

if __name__ == "__main__":
    main()

设置Cron任务

编辑Cron任务:

crontab -e

添加以下行来每分钟运行一次脚本:

* * * * * /usr/bin/python3 /path/to/distributed_cron.py

运行Redis服务器

确保Redis服务器正在运行:

sudo systemctl start redis-server

通过这种方式,你可以确保即使在多个节点上运行Cron任务,也只有一个节点能够执行定时任务。

0
看了该问题的人还看了