数据库节点
| 节点 | 地址 | 租户 | 角色 | 状态 |
|---|---|---|---|---|
| {{ node.name }}{{ node.code }} | {{ node.host }}:{{ node.port }} | {{ node.tenant_count }} | {{ Number(node.is_default) === 1 ? '默认节点' : '普通节点' }} | {{ Number(node.status) === 1 ? '正常' : '停用' }} |
| 暂无数据库节点 | ||||
最近同步任务
| ID | 租户 | 任务类型 | 状态 | 创建时间 |
|---|---|---|---|---|
| #{{ job.id }} | {{ job.owner_name || job.owner_user_id }} | {{ job.job_type }} | {{ job.status_label || jobStatus(job.status) }} | {{ formatTime(job.created_at) }} |
| 暂无同步任务 | ||||
{{ syncDomainInfo.label }}
{{ syncDomainInfo.description }}。统计、任务和进程均按当前业务展示。
{{ syncDomain === 'ads' ? '广告 API 与消息队列' : 'SP-API 与订单通知' }}
{{ syncDomain === 'ads' ? '管理广告应用凭据、授权回调与广告专用 SQS 队列。' : '管理卖家应用凭据、授权回调与订单通知 SQS 队列。' }}
广告同步范围
广告资料同步活动、广告组与投放对象;广告日报同步广告表现数据。同步计划由广告同步服务管理。
订单同步参数
适用于所有 Amazon 店铺。保存后无需重启,服务缓存最长 30 秒。已开始的任务保留原时间段,请求间隔按新配置执行。
共用凭据加密配置 SP-API 与广告共用
凭据加密配置
此密钥用于加解密 SP-API 与广告授权凭据,授权服务与同步服务须使用同一把。同步服务器连接数据库和 Redis 时使用各自的账号密码。
通知运行看板
仅管理员可见。按店铺检查订阅、接收进程和实际处理记录。
{{ notificationActionMessage }}
通知快照:{{ formatTime(syncNotifications.server_time) }} · 最近 {{ syncNotifications.history_days }} 天及所有未结束任务 · 共 {{ syncNotifications.total }} 个店铺
{{ item.shop_name || '店铺 #' + item.shop_id }} · {{ item.region || '区域未知' }}
用户 #{{ item.owner_user_id }} · 店铺 #{{ item.shop_id }} · 接收心跳 {{ formatTime(item.receiver_heartbeat_at) }}
最近订阅任务异常:{{ syncErrorLabel(item.subscription_task_error) }}
最近订阅任务 #{{ item.subscription_task.id }}:{{ jobStatus(item.subscription_task.status) }} · {{ formatTime(item.subscription_task.finished_at || item.subscription_task.created_at) }}。保存接收配置后仍需执行订阅任务。
| 通知类型 / 通道 | 订阅与运行 | 最近接收 / 处理 | 待处理 / 失败 | 查询 / 复用 | |
|---|---|---|---|---|---|
{{ notificationTypeLabel(row.notification_type) }}{{ row.transport === 'eventbridge' ? 'EventBridge → SQS' : 'SQS' }}技术详情{{ row.notification_type }}Destination:{{ row.destination_id || '未登记' }}Subscription:{{ row.subscription_id || '未登记' }} |
{{ notificationStateLabel(row.state) }}验证:{{ formatTime(row.verified_at) }}{{ syncErrorLabel(row.error_code) }} | {{ row.last_event_at ? '已保存报告完成信号' : '暂无完成信号' }}事件时间:{{ formatTime(row.last_event_at) }} | {{ row.last_received_at ? formatTime(row.last_received_at) : '暂无接收记录' }}处理:{{ row.last_success_at ? formatTime(row.last_success_at) : '暂无成功记录' }} | {{ row.pending }} / {{ row.failed }}{{ row.unclaimed }} 个到期超 5 分钟,尚未领取最长等待:{{ syncDuration(Math.max(0,syncNotifications.server_time-row.oldest_due_at)) }}近 15 分钟完成 {{ row.processed_15m || 0 }} 个失败数含已恢复的历史任务 | {{ row.api_calls }} / {{ row.coalesced }}成功任务记录的补查 / 复用 |
最近成功校准:{{ syncTypeLabel(calibration.job_type) }} {{ formatTime(calibration.finished_at) }}; 暂无记录
异常消息
全平台异常记录,不受上方店铺筛选影响。消息加密保留 7 天;修复原因后重放时仍会检查店铺归属和订阅。到期后无法恢复。
匹配 {{ syncNotifications?.exception_total || 0 }} 条,其中 {{ syncNotifications?.exception_expiring || 0 }} 条将在 24 小时内到期。
| 通知 | 原因 | 记录时间 | 操作 | |
|---|---|---|---|---|
| {{ notificationTypeLabel(item.notification_type) || '未知类型' }}#{{ item.id }} · 出现 {{ item.occurrences }} 次 | {{ notificationReason(item.reason) }}{{ ({held:'待处理',queued:'等待重放',replaying:'重放中',resolved:'已恢复',expired:'已过期'})[item.status] || item.status }} | {{ formatTime(item.last_seen_at) }}到期:{{ formatTime(item.expires_at) }} | ||
| 暂无匹配的异常消息 | ||||
数据更新时间
成功执行时间与数据进度分别展示;仅汇总已成功的店铺、站点及报表范围,不代表全量无缺口。
- 最近成功执行
- {{ formatTime(item.last_success_at) }}
- {{ item.job_type === 'ads_report' ? '最近报表已同步至(账户日期)' : '最近订单增量已同步至' }}
- {{ syncDataTime(item.data_until,item.job_type) }}
- 各范围中最早的成功执行
- {{ formatTime(item.oldest_scope_success_at) }}
- 已知范围中最早的数据进度
- {{ syncDataTime(item.oldest_data_until,item.job_type) }}
范围超过 5,000 个,当前为部分结果,请结合用户和任务记录检查。
广告小时数据
SP 流量与转化消息独立接收,和广告日报分别监控。
- 最新数据所属小时
- {{ syncDataTime(syncFreshness.stream.data_until,'ads_stream') }}
- 最近有效入库
- {{ formatTime(syncFreshness.stream.last_received_at) }}
- 最早已知订阅数据小时
- {{ syncDataTime(syncFreshness.stream.oldest_data_until,'ads_stream') }}
- 当前队列订阅
- {{ syncFreshness.stream.active || 0 }} 个活跃 / {{ syncFreshness.stream.subscriptions || 0 }} 个 · {{ syncFreshness.stream.errors || 0 }} 个异常
- 有小时进度的订阅
- {{ syncFreshness.stream.dated_subscriptions || 0 }} 个 · {{ syncFreshness.stream.held || 0 }} 个因用户设置暂缓
- 接收进程心跳
- {{ formatTime(syncFreshness.stream.receiver?.heartbeat_at) }}
- 队列积压(估计)
- {{ syncFreshness.stream.receiver?.pending_messages ?? '尚未采样' }}采样于 {{ formatTime(syncFreshness.stream.receiver?.metrics_at) }}
- 接收异常
- {{ syncErrorLabel(syncFreshness.stream.receiver.error_code) }}
数据小时是已收到消息的最新时间,不表示此前每小时完整。流量与转化可分批或延迟到达;暂停期间消息受队列保留期限制。
待处理事项
定位当前业务的异常与积压。
同步内容
按数据类型查看{{ syncDomainInfo.label }}任务。
接口响应情况 最近 15 分钟 · 当前服务节点
| 接口 | 请求数 | 平均 / 最慢 | 慢请求 ≥ 1 秒 | 失败 | 超 20 秒 | 浏览器超时上报 |
|---|---|---|---|---|---|---|
| {{ ({'admin.sync.overview':'运行概览','admin.sync.jobs':'任务记录','admin.sync.users':'用户状态','admin.sync.job':'任务详情','admin.sync.freshness':'数据进度'})[item.action] || item.action }} | {{ item.count }} | {{ item.average_ms }} / {{ item.max_ms }} ms | {{ item.slow_count }} | {{ item.error_count }} | {{ item.timeout_count }} | {{ item.client_timeout_count }} |
| 暂无接口统计,后续请求将自动记录 | ||||||
进程运行明细
心跳间隔约 10 秒,超过 60 秒未上报标为失联。共享进程可出现在两类同步中,当前任务按所属业务显示。
| 服务器 / 进程 | 状态 | 当前任务 | 支持类型 | PHP 内存 | 启动 / 心跳时间 | 当前异常 |
|---|---|---|---|---|---|---|
| {{ process.node_id }}{{ process.role }} · PID {{ process.pid }} | {{ process.health === 'busy' && process.current_job_in_domain === false ? '正在处理其他业务' : syncStateLabel(process.health) }} | {{ process.current_job_in_domain === false ? (process.current_job_domain === 'ads' ? '广告任务' : 'SP-API 任务') : '—' }} | {{ process.job_types.map(syncTypeLabel).join('、') || '—' }} | {{ (Number(process.memory_bytes) / 1048576).toFixed(1) }} MB | {{ formatTime(process.started_at) }}心跳 {{ formatTime(process.heartbeat_at) }} | {{ syncErrorLabel(process.last_error_code) }} |
| 暂无进程上报;启动同步服务后会自动显示 | ||||||
用户同步状态
任务数量仅统计{{ syncDomainInfo.label }}。开关仅控制当前业务,SP-API 与广告可以分别暂停、关闭或恢复。
| 用户 / 数据库节点 | 账号状态 | 同步设置 / 生效状态 | 等待 / 执行 | 近 24 小时 | 累计失败 | 最近成功同步 | 操作 |
|---|---|---|---|---|---|---|---|
| {{ user.name || user.username }} · #{{ user.id }}{{ user.username }} · {{ user.node_name || '未分配数据库节点' }} | {{ Number(user.status) === 1 ? '账号正常' : '账号停用' }}租户数据库当前不可用 | {{ syncControlLabel(user.sync_state) }}{{ syncUserState(user) }}设置于 {{ formatTime(user.sync_changed_at) }}{{ user.sync_reason }} | {{ user.stats.queued }} 等待 · {{ user.stats.running }} 执行{{ user.stats.retrying }} 等待重试 · {{ user.stats.expired }} 租约过期 | {{ user.stats.completed_24h }} 完成{{ user.stats.failed_24h }} 最终失败 | {{ user.stats.failed }} | {{ formatTime(user.stats.last_success_at) }}尚无同步任务 | |
| {{ syncUsersLoading ? '正在获取用户同步状态…' : '没有符合条件的用户' }} | |||||||
同步任务记录
仅显示{{ syncDomainInfo.label }}任务。店铺 ID 需结合用户 ID 定位。
| 任务 | 用户 / 店铺 | 状态 | 尝试次数 | 计划 / 完成时间 | 最近异常 | 操作 |
|---|---|---|---|---|---|---|
| #{{ job.id }} · {{ syncTypeLabel(job.job_type) }}{{ job.marketplace_id || '全部站点' }}{{ syncProgressLabel(job) }}{{ syncWaitLabel(job) }} | {{ job.owner_name || job.owner_username || '用户' }}用户 #{{ job.owner_user_id }} · 店铺 #{{ job.shop_id }} | {{ job.status_label || jobStatus(job.status) }}用户同步{{ syncControlLabel(job.sync_state) }},任务保留等待重试租约已过期 | {{ job.attempt_count }} / {{ job.max_attempts }} | {{ formatTime(job.scheduled_at) }}{{ job.finished_at ? '完成于 ' + formatTime(job.finished_at) : '尚未结束' }} | {{ syncErrorLabel(job.error_code) }}{{ syncIssue(job).note }} | |
| 没有符合条件的同步任务 | ||||||
| 用户 | 数据库 | 节点 | 子账号 | 登录 | 状态 | 操作 |
|---|---|---|---|---|---|---|
| {{ user.name }}#{{ user.id }} · {{ user.username }} | {{ user.database_name || '未开通' }}{{ user.schema_version || '-' }} | {{ user.node_name || '-' }}{{ user.node_code || '' }} | {{ user.subaccount_count }} | {{ user.login_count }} 次{{ formatTime(user.last_login_at) }} | {{ Number(user.status) === 1 ? '正常' : '停用' }} | |
| 暂无租户用户 | ||||||
| 节点 | 服务器 | 连接账号 | 租户 | 启用状态 | 自动连通检测 | 连接与建库测试 | 操作 |
|---|---|---|---|---|---|---|---|
| {{ node.name }}{{ node.code }} · 默认 | {{ node.host }}:{{ node.port }}{{ node.charset }} · {{ node.ssl_mode }} | {{ node.db_username || '未配置' }}{{ node.credential_source === 'saved' ? '后台保存' : node.credential_key + '_*' }}凭据读取异常 | {{ node.tenant_count }} | {{ Number(node.status) === 1 ? '启用' : '停用' }} | {{ nodeHealthState(node).label }}每 {{ node.health_check_interval_minutes }} 分钟 · 节点停用最近:{{ formatTime(node.health_checked_at) }} · {{ node.health_elapsed_ms }} ms{{ nodeHealthError(node) }} · 连续失败 {{ node.health_failures }} 次{{ Number(node.health_next_check_at) > 0 ? '下次:' + formatTime(node.health_next_check_at) : '保存后等待首次检测' }}结果已过期,请检查检测服务 | {{ nodeTests[node.id]?.state === 'success' ? '测试通过' : nodeTests[node.id]?.state === 'failed' ? '测试失败' : nodeTests[node.id]?.state === 'testing' ? '测试中…' : '未测试' }}{{ nodeTests[node.id].message }}{{ formatTime(nodeTests[node.id].checked_at) }} | |
| 暂无数据库节点 | |||||||
错误日志
记录当前后台服务的错误与警告,保留最近 30 天。服务器:{{ errorLogs.host || '读取中…' }}
| 时间 / 级别 | 来源 / 接口 | 错误信息 | 失败阶段 | 操作 |
|---|---|---|---|---|
| {{ formatTime(log.created_at) }}{{ errorLogLevel(log.level) }} | {{ errorLogSource(log.source) }}{{ log.context.action || log.context.path || '—' }} | {{ errorLogPhase(log.context.phase) }}用户 #{{ log.context.owner_user_id }} · 节点 #{{ log.context.node_id || '—' }} | ||
| {{ errorLogsLoading ? '正在读取日志…' : errorLogsError ? '日志读取失败' : '当前范围暂无匹配日志' }} | ||||
| 时间 | 管理员 | 动作 | 对象 | 详情 |
|---|---|---|---|---|
| {{ formatTime(log.created_at) }} | {{ log.admin_name }}{{ log.username }} | {{ log.action }} | {{ log.target_type }}{{ log.target_id }} | {{ detailText(log.detail) }} |
| 暂无审计记录 | ||||