diff --git a/.agents/skills/ulthon-timer/SKILL.md b/.agents/skills/ulthon-timer/SKILL.md index 8c4d242..9949450 100644 --- a/.agents/skills/ulthon-timer/SKILL.md +++ b/.agents/skills/ulthon-timer/SKILL.md @@ -201,6 +201,8 @@ nohup php /var/www/html/think timer --local --quiet & 多节点部署:每个容器各自启动 timer 进程,`runtime/node_id.lock` 在各自容器内独立生成(天然隔离),连同一个数据库即自动组成多节点集群。 +> **多节点部署注意(run_type=all 的任务)**:`run_type=all` 的定时任务(如 `nginx_log_import`)要求每节点各自采集本机数据,每节点必须用 `php think timer --local` 启动,确保 site 请求发往本机 `localhost` 而非共享 `site_domain`/LB,否则请求会落在随机节点上,导致采集错位(节点 A 的日志被节点 B 处理)。框架内置 Docker 部署栈已默认带 `--local`,手动/裸机部署时务必显式加上。 + ### 本地调试(指定请求 Host) site 任务会按站点域名发起请求,默认从 `sysconfig('site','site_domain')` 读取。 diff --git a/app/admin/scheme/NginxAccessLog.php b/app/admin/scheme/NginxAccessLog.php index 40fbbda..b6fb0e6 100644 --- a/app/admin/scheme/NginxAccessLog.php +++ b/app/admin/scheme/NginxAccessLog.php @@ -9,6 +9,7 @@ use app\common\scheme\attribute\Component; use app\common\scheme\attribute\Index; #[Table(name: 'ul_nginx_access_log', comment: 'nginx 访问日志明细(解析入库)')] +#[Index(columns: ['node_id', 'time_local'], name: 'idx_node_time', type: 'NORMAL')] #[Index(columns: ['time_local'], name: 'idx_time_local', type: 'NORMAL')] #[Index(columns: ['remote_addr'], name: 'idx_remote_addr', type: 'NORMAL')] #[Index(columns: ['status'], name: 'idx_status', type: 'NORMAL')] @@ -19,6 +20,9 @@ class NginxAccessLog extends BaseScheme #[Field(type: 'bigint', nullable: false, unsigned: true, autoIncrement: true, primary: true, comment: '主键ID')] public $id; + #[Field(type: 'varchar', length: 64, nullable: false, default: '', comment: '节点ID(区分不同采集节点)')] + public $node_id; + #[Field(type: 'varchar', length: 500, nullable: false, comment: '来源日志文件路径')] #[Component(type: 'text', options: [])] public $file_path; diff --git a/app/admin/scheme/NginxLogPosition.php b/app/admin/scheme/NginxLogPosition.php index a027479..ca8560b 100644 --- a/app/admin/scheme/NginxLogPosition.php +++ b/app/admin/scheme/NginxLogPosition.php @@ -9,12 +9,15 @@ use app\common\scheme\attribute\Component; use app\common\scheme\attribute\Index; #[Table(name: 'ul_nginx_log_position', comment: 'nginx 日志文件读取位置(增量读取状态)')] -#[Index(columns: ['file_path'], name: 'uniq_file_path', type: 'UNIQUE')] +#[Index(columns: ['node_id', 'file_path'], name: 'uniq_node_file', type: 'UNIQUE')] class NginxLogPosition extends BaseScheme { #[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)] public $id; + #[Field(type: 'varchar', length: 64, nullable: false, default: '', comment: '节点ID(区分不同采集节点)')] + public $node_id; + #[Field(type: 'varchar', length: 500, nullable: false, comment: '日志文件绝对路径')] #[Component(type: 'text', options: [])] public $file_path; diff --git a/app/admin/scheme/NginxStatHour.php b/app/admin/scheme/NginxStatHour.php index 887173f..526275f 100644 --- a/app/admin/scheme/NginxStatHour.php +++ b/app/admin/scheme/NginxStatHour.php @@ -8,13 +8,16 @@ use app\common\scheme\attribute\Field; use app\common\scheme\attribute\Index; #[Table(name: 'nginx_stat_hour', comment: 'nginx 按小时聚合统计')] -#[Index(columns: ['stat_date', 'stat_hour'], name: 'uniq_date_hour', type: 'UNIQUE')] +#[Index(columns: ['node_id', 'stat_date', 'stat_hour'], name: 'uniq_node_date_hour', type: 'UNIQUE')] #[Index(columns: ['stat_date'], name: 'idx_stat_date', type: 'NORMAL')] class NginxStatHour extends BaseScheme { #[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)] public $id; + #[Field(type: 'varchar', length: 64, nullable: false, default: '', comment: '节点ID(区分不同采集节点)')] + public $node_id; + #[Field(type: 'int', length: 11, nullable: false, unsigned: true, comment: '统计日期(YYYYMMDD)')] public $stat_date; diff --git a/app/admin/scheme/NginxStatReferer.php b/app/admin/scheme/NginxStatReferer.php index 3c64b5d..c3a17ce 100644 --- a/app/admin/scheme/NginxStatReferer.php +++ b/app/admin/scheme/NginxStatReferer.php @@ -8,13 +8,16 @@ use app\common\scheme\attribute\Field; use app\common\scheme\attribute\Index; #[Table(name: 'nginx_stat_referer', comment: 'nginx 按 Referer 来源域名聚合统计')] -#[Index(columns: ['stat_date', 'referer_domain'], name: 'uniq_date_referer', type: 'UNIQUE')] +#[Index(columns: ['node_id', 'stat_date', 'referer_domain'], name: 'uniq_node_date_referer', type: 'UNIQUE')] #[Index(columns: ['stat_date'], name: 'idx_stat_date', type: 'NORMAL')] class NginxStatReferer extends BaseScheme { #[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)] public $id; + #[Field(type: 'varchar', length: 64, nullable: false, default: '', comment: '节点ID(区分不同采集节点)')] + public $node_id; + #[Field(type: 'int', length: 11, nullable: false, unsigned: true, comment: '统计日期(YYYYMMDD)')] public $stat_date; diff --git a/app/admin/scheme/NginxStatUa.php b/app/admin/scheme/NginxStatUa.php index 5171001..73649b1 100644 --- a/app/admin/scheme/NginxStatUa.php +++ b/app/admin/scheme/NginxStatUa.php @@ -8,13 +8,16 @@ use app\common\scheme\attribute\Field; use app\common\scheme\attribute\Index; #[Table(name: 'nginx_stat_ua', comment: 'nginx 按 User-Agent 聚合统计')] -#[Index(columns: ['stat_date', 'ua_type', 'ua_name'], name: 'uniq_date_type_name', type: 'UNIQUE')] +#[Index(columns: ['node_id', 'stat_date', 'ua_type', 'ua_name'], name: 'uniq_node_date_type_name', type: 'UNIQUE')] #[Index(columns: ['stat_date'], name: 'idx_stat_date', type: 'NORMAL')] class NginxStatUa extends BaseScheme { #[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)] public $id; + #[Field(type: 'varchar', length: 64, nullable: false, default: '', comment: '节点ID(区分不同采集节点)')] + public $node_id; + #[Field(type: 'int', length: 11, nullable: false, unsigned: true, comment: '统计日期(YYYYMMDD)')] public $stat_date; diff --git a/app/admin/scheme/NginxStatUrl.php b/app/admin/scheme/NginxStatUrl.php index 84cffd3..1202491 100644 --- a/app/admin/scheme/NginxStatUrl.php +++ b/app/admin/scheme/NginxStatUrl.php @@ -8,13 +8,16 @@ use app\common\scheme\attribute\Field; use app\common\scheme\attribute\Index; #[Table(name: 'nginx_stat_url', comment: 'nginx 按 URL 聚合统计')] -#[Index(columns: ['stat_date', 'uri'], name: 'uniq_date_uri', type: 'UNIQUE')] +#[Index(columns: ['node_id', 'stat_date', 'uri'], name: 'uniq_node_date_uri', type: 'UNIQUE')] #[Index(columns: ['stat_date'], name: 'idx_stat_date', type: 'NORMAL')] class NginxStatUrl extends BaseScheme { #[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)] public $id; + #[Field(type: 'varchar', length: 64, nullable: false, default: '', comment: '节点ID(区分不同采集节点)')] + public $node_id; + #[Field(type: 'int', length: 11, nullable: false, unsigned: true, comment: '统计日期(YYYYMMDD)')] public $stat_date; diff --git a/app/admin/view/nginx/access_log/index.html b/app/admin/view/nginx/access_log/index.html index ef77867..2d1ba11 100644 --- a/app/admin/view/nginx/access_log/index.html +++ b/app/admin/view/nginx/access_log/index.html @@ -1,5 +1,47 @@
{$pos.file_path}
+