# DataX 同步脚本定时执行指南

本文档介绍了如何定时执行 DataX 同步脚本的两种主要方式：宿主机 crontab 和容器内 crontab。

## 1. 宿主机 Crontab 方式

### 1.1 原理

在宿主机上使用 `crontab` 工具，通过 `docker-compose exec` 命令定期在 DataX 容器内执行同步脚本。

### 1.2 配置步骤

#### 1.2.1 创建执行脚本

首先，在宿主机上创建一个执行脚本，用于运行 DataX 作业：

```bash
# 创建脚本目录
mkdir -p /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts

# 创建产品同步脚本
touch /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_products.sh
chmod +x /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_products.sh

# 创建订单同步脚本
touch /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_orders.sh
chmod +x /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_orders.sh
```

#### 1.2.2 编写脚本内容

**产品同步脚本** (`sync_products.sh`)：

```bash
#!/bin/bash

# 设置工作目录
cd /Users/zksu/Developer/work/workcode/API-vendor/container

# 执行 DataX 作业
docker-compose exec -T datax python /datax/bin/datax.py /datax/job/restful_to_mysql_products.json > /Users/zksu/Developer/work/workcode/API-vendor/container/datax/log/products_sync_$(date +%Y%m%d_%H%M%S).log 2>&1
```

**订单同步脚本** (`sync_orders.sh`)：

```bash
#!/bin/bash

# 设置工作目录
cd /Users/zksu/Developer/work/workcode/API-vendor/container

# 执行 DataX 作业
docker-compose exec -T datax python /datax/bin/datax.py /datax/job/restful_to_mysql_orders.json > /Users/zksu/Developer/work/workcode/API-vendor/container/datax/log/orders_sync_$(date +%Y%m%d_%H%M%S).log 2>&1
```

#### 1.2.3 配置 Crontab

1. 编辑宿主机的 crontab 配置：

```bash
crontab -e
```

2. 添加定时任务：

```bash
# 每小时执行一次产品同步
0 * * * * /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_products.sh

# 每2小时执行一次订单同步
0 */2 * * * /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_orders.sh

# 每天凌晨3点执行所有同步
0 3 * * * /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_products.sh && /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_orders.sh
```

3. 保存并退出编辑器。

### 1.3 优点

- **配置简单**：无需修改 Docker 容器配置
- **易于管理**：所有定时任务集中在宿主机管理
- **日志管理方便**：可以将日志输出到宿主机指定位置
- **不依赖容器状态**：即使容器重启，定时任务依然有效

### 1.4 缺点

- **依赖宿主机**：宿主机故障会导致定时任务失效
- **需要宿主机权限**：需要在宿主机上配置 crontab

## 2. 容器内 Crontab 方式

### 2.1 原理

在 DataX 容器内部安装并配置 `crontab` 服务，直接在容器内定时执行同步脚本。

### 2.2 配置步骤

#### 2.2.1 自定义 Docker 镜像

1. 创建 `Dockerfile`：

```bash
mkdir -p /Users/zksu/Developer/work/workcode/API-vendor/container/datax/docker
```

2. 编写 `Dockerfile`：

```dockerfile
FROM beginor/datax

# 安装 crontab
RUN apt-get update && apt-get install -y cron && rm -rf /var/lib/apt/lists/*

# 创建 crontab 配置文件
RUN touch /etc/crontab /etc/cron.d/datax-cron

# 给执行权限
RUN chmod 0644 /etc/cron.d/datax-cron

# 创建日志目录
RUN mkdir -p /var/log/cron

# 复制作业脚本
COPY job/ /datax/job/

# 设置环境变量
ENV TZ=Asia/Shanghai

# 启动 crontab 服务
CMD service cron start && tail -f /dev/null
```

3. 构建自定义镜像：

```bash
cd /Users/zksu/Developer/work/workcode/API-vendor/container/datax/docker
docker build -t custom/datax .
```

4. 修改 `docker-compose.yml` 中的镜像：

```yaml
datax:
  image: custom/datax
  # ... 其他配置不变
```

#### 2.2.2 配置容器内 Crontab

1. 进入容器：

```bash
docker-compose exec datax bash
```

2. 编辑 crontab 配置：

```bash
crontab -e
```

3. 添加定时任务：

```bash
# 每小时执行一次产品同步
0 * * * * python /datax/bin/datax.py /datax/job/restful_to_mysql_products.json > /datax/log/products_sync_$(date +\%Y\%m\%d_\%H\%M\%S).log 2>&1

# 每2小时执行一次订单同步
0 */2 * * * python /datax/bin/datax.py /datax/job/restful_to_mysql_orders.json > /datax/log/orders_sync_$(date +\%Y\%m\%d_\%H\%M\%S).log 2>&1
```

4. 保存并退出编辑器。

5. 重启 crontab 服务：

```bash
service cron restart
```

### 2.3 优点

- **容器化管理**：定时任务与容器绑定，便于迁移和部署
- **不依赖宿主机**：容器可以在任何 Docker 环境中运行，定时任务依然有效
- **隔离性好**：定时任务只影响当前容器

### 2.4 缺点

- **配置复杂**：需要自定义 Docker 镜像
- **日志管理**：日志默认保存在容器内部，需要通过卷挂载到宿主机
- **容器重启影响**：容器重启后需要确保 crontab 服务自动启动

## 3. 定时任务监控

### 3.1 日志监控

- **宿主机方式**：直接查看宿主机上的日志文件
- **容器内方式**：通过 `docker-compose logs -f datax` 查看容器日志，或通过卷挂载查看日志文件

### 3.2 执行状态监控

1. **创建监控脚本**：

```bash
#!/bin/bash

# 检查产品同步日志
PRODUCTS_LOG=$(ls -t /Users/zksu/Developer/work/workcode/API-vendor/container/datax/log/products_sync_*.log | head -1)
if [ -f "$PRODUCTS_LOG" ]; then
  echo "产品同步最后执行时间：$(date -r $PRODUCTS_LOG)"
  echo "执行结果：$(tail -1 $PRODUCTS_LOG)"
else
  echo "产品同步日志不存在"
fi

# 检查订单同步日志
ORDERS_LOG=$(ls -t /Users/zksu/Developer/work/workcode/API-vendor/container/datax/log/orders_sync_*.log | head -1)
if [ -f "$ORDERS_LOG" ]; then
  echo "订单同步最后执行时间：$(date -r $ORDERS_LOG)"
  echo "执行结果：$(tail -1 $ORDERS_LOG)"
else
  echo "订单同步日志不存在"
fi
```

2. 给脚本执行权限：

```bash
chmod +x /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/check_sync_status.sh
```

3. 执行监控脚本：

```bash
/Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/check_sync_status.sh
```

### 3.3 告警机制

可以结合以下工具实现告警机制：

- **Prometheus + Grafana**：监控同步任务执行状态和时间
- **ELK Stack**：收集和分析同步日志，设置告警规则
- **企业微信/钉钉机器人**：通过脚本检查执行结果，发送告警通知

## 4. 最佳实践

### 4.1 选择合适的方式

- **小型项目/测试环境**：推荐使用宿主机 crontab 方式，配置简单
- **大型项目/生产环境**：推荐使用容器内 crontab 方式，便于管理和迁移
- **需要高可用**：考虑使用专门的任务调度工具，如 Apache Airflow、XXL-JOB 等

### 4.2 日志管理

- **设置合理的日志保留时间**：避免日志文件过大
- **使用日志轮转**：定期压缩和清理旧日志
- **集中日志管理**：将日志发送到 ELK 或其他日志管理系统

### 4.3 错误处理

- **添加重试机制**：在脚本中添加失败重试逻辑
- **设置超时时间**：避免单个任务执行时间过长
- **及时告警**：同步失败时立即发送告警通知

### 4.4 性能优化

- **合理设置同步频率**：根据数据更新频率设置合适的同步间隔
- **使用增量同步**：只同步新增或修改的数据，减少同步时间
- **调整并发数**：根据系统资源和 API 限制调整 DataX 的并发通道数

## 5. 示例：完整的宿主机 Crontab 配置

### 5.1 产品同步脚本 (`sync_products.sh`)

```bash
#!/bin/bash

# 设置工作目录
cd /Users/zksu/Developer/work/workcode/API-vendor/container

# 记录开始时间
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始执行产品同步..." > /tmp/products_sync_start.log

# 执行 DataX 作业
docker-compose exec -T datax python /datax/bin/datax.py /datax/job/restful_to_mysql_products.json > /Users/zksu/Developer/work/workcode/API-vendor/container/datax/log/products_sync_$(date +%Y%m%d_%H%M%S).log 2>&1

# 检查执行结果
if [ $? -eq 0 ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 产品同步执行成功" >> /tmp/products_sync_start.log
else
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 产品同步执行失败" >> /tmp/products_sync_start.log
    # 发送告警通知（示例：企业微信机器人）
    curl -s -H "Content-Type: application/json" -d '{"msgtype": "text", "text": {"content": "产品同步执行失败，请查看日志"}}' https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your_webhook_key
fi
```

### 5.2 Crontab 配置

```bash
# 每小时执行一次产品同步
0 * * * * /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_products.sh

# 每2小时执行一次订单同步
0 */2 * * * /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_orders.sh

# 每天凌晨3点执行所有同步
0 3 * * * /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_products.sh && /Users/zksu/Developer/work/workcode/API-vendor/container/datax/scripts/sync_orders.sh

# 每天凌晨4点清理7天前的日志
0 4 * * * find /Users/zksu/Developer/work/workcode/API-vendor/container/datax/log -name "*.log" -mtime +7 -delete
```

## 6. 扩展阅读

- [Crontab 语法详解](https://crontab.guru/)
- [Docker 容器中使用 Crontab](https://docs.docker.com/config/containers/multi-service_container/)
- [Apache Airflow 官方文档](https://airflow.apache.org/docs/)
- [XXL-JOB 官方文档](https://www.xuxueli.com/xxl-job/)
