fix(部署): 聚水潭发货数据定时同步失败自动重试并留日志,晚上补拉一次 #1183
@ -253,6 +253,8 @@ CRON_TZ=Asia/Shanghai
|
||||
* * * * * root /usr/bin/flock -n /run/caiwu-account-mapping-resync.lock /bin/sh /opt/caiwuxitong/run-finance-batch.sh store-receipt:auto-resync --quiet >/dev/null 2>&1
|
||||
* * * * * root /usr/bin/flock -n /run/caiwu-account-bills-export.lock /bin/sh /opt/caiwuxitong/run-finance-batch.sh account-bills:exports:run --quiet >/dev/null 2>&1
|
||||
28 1 * * * root /bin/sh /opt/caiwuxitong/run-finance-batch.sh jushuitan:sync-shipping --days=3 >/dev/null 2>&1
|
||||
# 聚水潭发货数据:凌晨部分出库单商品明细未到齐、副本库也可能超时,晚上再补拉最近 3 天。
|
||||
28 21 * * * root /bin/sh /opt/caiwuxitong/run-finance-batch.sh jushuitan:sync-shipping --days=3 >/dev/null 2>&1
|
||||
# 头条放心购(店铺收款账户账单 › 抖音账户)资金流水:每天 09:30 定点把该渠道所用
|
||||
# 原始账单镜像追平一次,保证上班前当日/前一日流水已进系统,而不是等每分钟轮转慢慢走。
|
||||
30 9 * * * root /usr/bin/flock -w 1800 /run/caiwu-upstream-sync.lock /usr/bin/docker exec -u www-data caiwu_app php artisan business-mirror:sync-tables operations_replica.rpt.jst_originalBillInfo --max-batches=20 --quiet >/dev/null 2>&1
|
||||
|
||||
@ -257,6 +257,8 @@ CRON_TZ=Asia/Shanghai
|
||||
* * * * * root /usr/bin/flock -n /run/caiwu-account-mapping-resync.lock /bin/sh /opt/caiwuxitong/run-finance-batch.sh store-receipt:auto-resync --quiet >/dev/null 2>&1
|
||||
* * * * * root /usr/bin/flock -n /run/caiwu-account-bills-export.lock /bin/sh /opt/caiwuxitong/run-finance-batch.sh account-bills:exports:run --quiet >/dev/null 2>&1
|
||||
28 1 * * * root /bin/sh /opt/caiwuxitong/run-finance-batch.sh jushuitan:sync-shipping --days=3 >/dev/null 2>&1
|
||||
# 聚水潭发货数据:凌晨部分出库单商品明细未到齐、副本库也可能超时,晚上再补拉最近 3 天。
|
||||
28 21 * * * root /bin/sh /opt/caiwuxitong/run-finance-batch.sh jushuitan:sync-shipping --days=3 >/dev/null 2>&1
|
||||
# 头条放心购(店铺收款账户账单 › 抖音账户)资金流水:每天 09:30 定点把该渠道所用
|
||||
# 原始账单镜像追平一次,保证上班前当日/前一日流水已进系统,而不是等每分钟轮转慢慢走。
|
||||
30 9 * * * root /usr/bin/flock -w 1800 /run/caiwu-upstream-sync.lock /usr/bin/docker exec -u www-data caiwu_app php artisan business-mirror:sync-tables operations_replica.rpt.jst_originalBillInfo --max-batches=20 --quiet >/dev/null 2>&1
|
||||
|
||||
@ -64,4 +64,28 @@ esac
|
||||
RUN_MIGRATIONS=0
|
||||
export IMAGE_TAG RUN_MIGRATIONS
|
||||
# Mutating jobs hold the upstream lock; read-only exports use their own single-worker lock.
|
||||
if [ "$1" = 'jushuitan:sync-shipping' ]; then
|
||||
# 聚水潭副本库偶发超时会让整次发货数据同步失败(当晚最近几天漏单):
|
||||
# 输出里有"同步失败"时自动重试,每次输出留日志;只有警告(未写"同步失败")不重试。
|
||||
sync_log="${CAIWU_JST_SYNC_LOG:-$REMOTE_DIR/jst-sync-shipping.log}"
|
||||
sync_attempts="${CAIWU_JST_SYNC_ATTEMPTS:-3}"
|
||||
if [ -f "$sync_log" ] && [ "$(wc -c <"$sync_log")" -gt 5000000 ]; then
|
||||
mv -f "$sync_log" "$sync_log.1"
|
||||
fi
|
||||
sync_out="$(mktemp)"
|
||||
trap 'rm -f "$sync_out"' EXIT
|
||||
attempt=1
|
||||
while :; do
|
||||
echo "== $(date '+%Y-%m-%d %H:%M:%S') attempt $attempt/$sync_attempts: $*" >>"$sync_log"
|
||||
rc=0
|
||||
docker compose -f compose.jiangling.yml --profile batch run --rm -T --no-deps batch "$@" >"$sync_out" 2>&1 || rc=$?
|
||||
tr '\r' '\n' <"$sync_out" | grep -v '已扫描' | tail -n 60 >>"$sync_log" || true
|
||||
echo "== rc=$rc" >>"$sync_log"
|
||||
if [ "$rc" -eq 0 ] || ! grep -q '同步失败' "$sync_out" || [ "$attempt" -ge "$sync_attempts" ]; then
|
||||
exit "$rc"
|
||||
fi
|
||||
attempt=$((attempt + 1))
|
||||
sleep "${CAIWU_JST_SYNC_RETRY_WAIT:-300}"
|
||||
done
|
||||
fi
|
||||
docker compose -f compose.jiangling.yml --profile batch run --rm -T --no-deps batch "$@"
|
||||
|
||||
@ -35,6 +35,42 @@ class FinanceBatchIsolationTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function test_shipping_sync_retries_after_upstream_failure_and_keeps_a_log(): void
|
||||
{
|
||||
$directory = sys_get_temp_dir() . '/caiwu-jst-retry-' . bin2hex(random_bytes(6));
|
||||
mkdir($directory);
|
||||
// 第一次同步输出"同步失败"(副本库超时),第二次成功
|
||||
file_put_contents($directory . '/docker', '#!/bin/sh' . "\n"
|
||||
. 'if [ "$1" = inspect ]; then echo caiwu_akaunting:123456789abc; exit 0; fi' . "\n"
|
||||
. 'n=$(cat "$CAIWU_REMOTE_DIR/count" 2>/dev/null || echo 0); n=$((n + 1)); echo $n > "$CAIWU_REMOTE_DIR/count"' . "\n"
|
||||
. 'if [ $n -eq 1 ]; then echo "同步失败:Adaptive Server connection timed out"; exit 1; fi' . "\n"
|
||||
. 'echo "同步完成"; exit 0' . "\n");
|
||||
chmod($directory . '/docker', 0700);
|
||||
try {
|
||||
$process = new Process(
|
||||
['sh', dirname(__DIR__, 3) . '/deploy/run-finance-batch.sh', 'jushuitan:sync-shipping', '--days=3'],
|
||||
$directory,
|
||||
[
|
||||
'PATH' => $directory . ':' . getenv('PATH'), 'CAIWU_REMOTE_DIR' => $directory,
|
||||
'CAIWU_UPSTREAM_LOCK' => $directory . '/sync.lock', 'CAIWU_BATCH_LOCK_WAIT' => '0.1',
|
||||
'CAIWU_JST_SYNC_RETRY_WAIT' => '0',
|
||||
],
|
||||
);
|
||||
$process->run();
|
||||
|
||||
$this->assertTrue($process->isSuccessful(), $process->getErrorOutput());
|
||||
$this->assertSame('2', trim((string) file_get_contents($directory . '/count')));
|
||||
$log = (string) file_get_contents($directory . '/jst-sync-shipping.log');
|
||||
$this->assertStringContainsString('attempt 1/3', $log);
|
||||
$this->assertStringContainsString('同步失败', $log);
|
||||
$this->assertStringContainsString('attempt 2/3', $log);
|
||||
$this->assertStringContainsString('同步完成', $log);
|
||||
} finally {
|
||||
foreach (glob($directory . '/*') as $path) { unlink($path); }
|
||||
rmdir($directory);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string,string|null> $environment */
|
||||
private function runBatch(
|
||||
string $directory,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user