# ql **Repository Path**: deshuofa/ql ## Basic Information - **Project Name**: ql - **Description**: php麒麟面板(参考青龙面板) - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-27 - **Last Updated**: 2026-10-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ql — PHP 定时任务调度面板 > 一个轻量级的「青龙类」任务调度面板:由系统 Cron 或外部定时服务驱动调度器与执行器, > 支持多 Cron 表达式、执行队列、失败重试、日志查看、后台管理与 API 调用。 > 运行环境:PHP 8.3 + MySQL 5.7+ / MariaDB 10.2+,已在虚拟主机环境验证可用。 ## 简介 ql 使用 PHP + MySQL 实现任务调度与执行,整体分为三层: - **调度器 `scheduler.php`**:由系统 Cron 或外部定时服务每分钟触发,判断任务是否到期,写入执行队列 `task_queue`,并定期清理日志与历史记录。 - **执行器 `executor.php`**:由系统 Cron 或外部定时服务每分钟触发,从队列取 `pending` 任务,运行 `scripts/` 下的脚本,写日志、按失败次数重试。 - **后台 `admin/` 与接口 `api/`**:任务增删改查、脚本管理、环境变量、日志查看、Token 管理等。 调度器与执行器均带文件锁(`data/*.lock`),并通过 API Token 鉴权,避免重复运行和未授权访问。 ## 功能特性 - 多 Cron 表达式:单个任务支持配置多个 Cron(`tasks.cron_exprs` 存 JSON 数组) - 执行队列:`task_queue` 记录 pending/running/success/failed,带 `scheduled_at` 与重试计数 - 失败重试:`config.php` 中 `max_retry` 控制最大重试次数 - 并发控制:调度器/执行器文件锁,执行器分批取任务(`executor_batch_size`) - 后台管理:任务、脚本、环境变量、日志、设置、Token - API 接口:`api/` 提供任务、脚本、日志、Token 等接口,使用 API Token 鉴权 - 防暴力破解:登录失败次数限制与锁定(`login_max_fail` / `login_lock_seconds`) - 时区与调试:`timezone` 默认 `Asia/Shanghai`,`debug` 开关 - 定时触发灵活:支持主机 Cron、curl/wget 调用、cron-job.org 等外部定时服务 ## 环境要求 - PHP 8.3(需 `pdo_mysql`、`json`、`curl` 扩展) - MySQL 5.7+ / MariaDB 10.2+,字符集 `utf8mb4` - 支持 Cron 定时任务、允许触发 PHP 的虚拟主机或服务器;或使用 cron-job.org 等外部定时服务 - 可写目录:`data/`(锁文件)、日志目录 ## 目录结构 ``` ql/ ├── admin/ # 后台页面(登录、任务、脚本、日志、设置等) ├── api/ # 接口(任务/脚本/环境/日志/Token 等) ├── lib/ # 公共类库 │ ├── Db.php # 数据库单例 │ ├── Cron.php # Cron 表达式解析 │ ├── Auth.php # API Token 鉴权 │ ├── AdminAuth.php # 后台登录鉴权 │ ├── TaskRunner.php # 任务执行逻辑 │ ├── Setting.php # 全局配置读写 │ ├── Env.php # 环境变量 │ ├── HttpClient.php # HTTP 客户端 │ ├── QingLongApi.php # 青龙 API 封装 │ ├── SupabaseAuth.php# Supabase 鉴权 │ └── Response.php # 统一响应 ├── scripts/ # 被调度的脚本(当前含 backup.php、scripts.json) ├── config.php # 全局配置 ├── scheduler.php # 调度器 ├── executor.php # 执行器 ├── install.sql # 数据库初始化 ├── LICENSE # MIT 许可证 └── README.md ``` ## 快速开始 ### 1. 获取代码 ```bash git clone https://gitee.com/deshuofa/ql.git cd ql mkdir -p data ``` ### 2. 初始化数据库 ```bash mysql -u <用户> -p <数据库名> < install.sql ``` ### 3. 修改配置 编辑 `config.php`,填写数据库连接等信息: ```php 'db' => [ 'host' => 'localhost', 'port' => 3306, 'name' => '<数据库名>', 'user' => '<用户名>', 'pass' => '<密码>', 'charset' => 'utf8mb4', ], ``` 其他可调项: | 配置项 | 默认值 | 说明 | |--------|--------|------| | `max_execution_time` | 250 | 执行器总时间上限(秒) | | `executor_batch_size` | 5 | 执行器一次从队列取几条 | | `max_retry` | 2 | 失败最大重试次数 | | `admin_token_ttl` | 86400 | 后台 Token 有效期(秒) | | `login_max_fail` | 5 | 登录最大失败次数 | | `login_lock_seconds` | 900 | 登录锁定秒数 | | `timezone` | `Asia/Shanghai` | 时区 | | `debug` | `false` | 调试模式,生产环境设为 false | ### 4. 部署 Web 将项目放到 Web 根目录,或配置虚拟主机指向项目根目录,访问 `admin/` 进入后台。 ### 5. 配置定时触发 调度器与执行器需要每分钟触发一次。根据环境选择以下任一方式(详见「虚拟主机部署」)。 ## 虚拟主机部署(已验证) 本项目已在虚拟主机环境完成部署验证,可直接用于支持 Cron 的虚拟主机,或配合 cron-job.org 等外部定时服务使用。 ### 部署前提 - PHP 8.3,启用 `pdo_mysql`、`json`、`curl` - 可创建 MySQL 数据库并导入 `install.sql` - 主机提供 Cron / 计划任务,或使用 cron-job.org 等外部定时服务 - `data/` 与日志目录可写 ### 部署步骤 1. 上传代码到 Web 目录,创建 `data/` 并设可写 2. 导入 `install.sql`,修改 `config.php` 数据库配置 3. 访问 `admin/` 登录后台,立即修改密码、替换占位 Token 4. 配置定时触发(见下) ### 定时触发方式 **方式 A:主机 Cron + CLI 执行(推荐)** ```bash * * * * * /usr/bin/php /home/<用户>/public_html/ql/scheduler.php >> /home/<用户>/ql_data/scheduler.log 2>&1 * * * * * /usr/bin/php /home/<用户>/public_html/ql/executor.php >> /home/<用户>/ql_data/executor.log 2>&1 ``` **方式 B:主机 Cron + URL 调用(无 CLI 权限时)** ```bash * * * * * curl -s "https://<域名>/ql/scheduler.php?token=<调度器Token>" > /dev/null 2>&1 * * * * * curl -s "https://<域名>/ql/executor.php?token=<执行器Token>" > /dev/null 2>&1 ``` **方式 C:cron-job.org(无主机 Cron 权限时)** 使用 [cron-job.org](https://console.cron-job.org/) 在线服务定时触发调度器与执行器: 1. 注册并登录 console.cron-job.org 2. 创建两个 Cron Job,URL 分别填: - `https://<域名>/ql/scheduler.php?token=<调度器Token>` - `https://<域名>/ql/executor.php?token=<执行器Token>` 3. 执行间隔设为 **每分钟**(免费版支持最短 1 分钟) 4. 在 Advanced 设置中按需添加 Header(Token 传递方式以 `lib/Auth.php` 为准) > **重要限制**:cron-job.org 免费版单次请求超时 **30 秒**,超时后会断开连接。本项目的执行器默认 `max_execution_time` 为 250 秒,若任务执行时间可能超过 30 秒,需注意: > - 将长任务拆分或优化到 30 秒内完成 > - 或将 `config.php` 中 `max_execution_time` 调低至 25 秒左右,确保执行器在 cron-job.org 超时前正常退出 > - 或升级 cron-job.org 会员(超时延长至 5 分钟) > 调度器/执行器均带文件锁,重复触发会被跳过;若通过 Web/FPM 调用,脚本会先 `fastcgi_finish_request()` 再后台执行,CLI 下不受影响。 ### 已验证环境 - 虚拟主机 + PHP 8.3 + MySQL,定时触发调度器与执行器,任务调度与执行正常 ### 虚拟主机注意事项 - **Cron 频率**:部分主机最短间隔较长,会影响调度精度,按主机限制调整即可 - **cron-job.org 超时**:免费版 30 秒断连,执行器需确保单次运行在 30 秒内,或调整 `max_execution_time` - **执行时间限制**:Web 方式受 `max_execution_time` 与 FPM 超时限制,长任务建议 CLI - **文件锁**:确认主机文件系统支持 `flock`;NFS 共享存储可能不可靠 - **路径**:cron 中 `php` 用绝对路径(`which php` 查看) - **日志目录**:确保 `data/` 与任务 `log_dir` 可写 - **禁止外部访问**:`data/`、`config.php`、`install.sql` 应通过 `.htaccess` 或主机规则禁止直接访问 ### 加固示例(Apache `.htaccess`) 放在项目根目录: ```apache Require all denied RewriteRule ^data/ - [F,L] ``` Nginx 主机: ```nginx location ~ ^/(data|config\.php|install\.sql) { deny all; } ``` ## 后台与登录 - 入口:`admin/index.php` - 初始密码:`admin123`(`install.sql` 中写入 `settings.admin_password` 的 bcrypt 哈希) - **部署后请立即在后台修改密码** ## API Token `install.sql` 预置了 3 个占位 Token(`REPLACE_WITH_RANDOM_TOKEN_*`,分别用于 D服务、调度器 Cron、执行器 Cron),并带有 `scopes`(允许的入口,逗号分隔,空表示全部)与 `status` 字段。 - **部署后请立即在后台重新生成或替换为随机值** - 调度器/执行器通过 `Auth::verify($db, 'scheduler'/'executor')` 校验 Token - API 调用需携带对应 Token(具体头/参数以 `lib/Auth.php` 实现为准) ## 数据表 | 表 | 说明 | |----|------| | `tasks` | 任务定义(名称、脚本路径、参数 JSON、多个 Cron、日志目录、状态、上次调度时间) | | `task_queue` | 执行队列(任务、计划时间、状态、开始/结束时间、日志路径、重试次数、错误摘要) | | `settings` | 全局配置(后台密码、登录失败计数、锁定截止时间等) | | `admin_tokens` | 后台临时 Token(有效期、最后使用时间) | | `api_tokens` | 外部服务 API Token(用途、scopes、状态、最后使用时间) | ## 脚本管理 - 脚本放在 `scripts/` 目录,`tasks.script_file` 存相对 `scripts/` 的路径 - `scripts/scripts.json` 维护脚本元信息(以后台/接口实际读取为准) - 执行器通过 `TaskRunner` 运行脚本并写日志到任务的 `log_dir` ## PHP 8.3 兼容性 本项目在 PHP 8.3 下开发/运行。若从旧版本迁移,注意: - PHP 8.2+ 弃用动态属性,类中请显式声明属性或加 `#[AllowDynamicProperties]` - 弃用 `${var}` 字符串插值,请改用 `{$var}` - 弃用 `utf8_encode` / `utf8_decode`,请改用 `mb_convert_encoding` - 内置函数传 `null` 到非 nullable 参数会告警,注意判空 - 调度器/执行器在 CLI 下运行,`fastcgi_finish_request()` 已做 `function_exists` 判断,不影响 CLI 执行 ## 常见问题 **Q: 任务没有被调度?** A: 确认定时触发在跑 `scheduler.php`(主机 Cron 或 cron-job.org),`tasks.status = 1`,且 `cron_exprs` 与当前时间匹配。 **Q: 任务一直在 pending?** A: 确认 `executor.php` 的定时触发在运行,且 `data/` 目录可写(锁文件)。 **Q: 数据库连接失败?** A: 核对 `config.php` 的 `db` 配置,确认已执行 `install.sql`。 **Q: 后台登录被锁定?** A: 达到 `login_max_fail` 次会锁定 `login_lock_seconds` 秒,可等待或清理 `settings` 中的 `login_lock_until`。 **Q: 虚拟主机 Cron 频率有限制怎么办?** A: 本项目已在支持 Cron 的虚拟主机验证可用;若主机最短间隔较长,调度精度会受影响,按主机限制调整即可,或改用 cron-job.org。 **Q: 用 cron-job.org 触发执行器,任务执行到一半被中断?** A: cron-job.org 免费版 30 秒超时断连。建议将 `max_execution_time` 设为 25 左右,或拆分任务,或升级 cron-job.org 会员。 **Q: 如何更新?** A: `git pull`;如表结构有变更,按新的 `install.sql` 增量执行。 ## 安全建议 - 立即修改后台初始密码,替换所有占位 API Token - 生产环境将 `debug` 设为 `false` - 限制 `admin/`、`api/` 访问来源,启用 HTTPS - `config.php` 中的数据库密码注意文件权限 - 虚拟主机上用 `.htaccess` 或主机规则禁止访问 `data/`、`config.php`、`install.sql` - 使用 cron-job.org 时,URL 中的 Token 会出现在第三方服务日志中,建议使用独立 Token 并定期轮换 ## 许可证 本项目采用 [MIT License](LICENSE) 开源。 ## 免责声明 本项目仅供学习与内部使用,请自行评估安全性与合规性,使用风险自负。