对接方新加了一台服务器后签名就偶尔报过期,同一套账号其它机器都正常,只坏一台是什么情况?
签名隔几个小时报一次过期,而且只有新加的那台机器在报,多数不是密钥配错,也不是我们这边窗口设得太窄,而是那台机器的系统时钟在慢慢漂。容器时钟跟随宿主、虚机迁移或宿主休眠后时间没有补步进、内网又不通外部时间源,偏差一点点累积,攒过窗口边界就开始零星失败。按 2026 年对接类项目的常见做法,签名时间窗多落在 3~10 分钟这个经验区间,这个宽度能容忍一次时间同步的延迟;想靠放宽窗口去覆盖一台已经漂了十几分钟的机器,等于把可被重放的时间面一起放宽。稳妥顺序是先把那台机器的基准时间对住,再核对时间戳的单位与时区,最后才谈窗口和 nonce。
只有一台报错,先怀疑时钟,别急着改窗口
窗口设窄的典型表现是成片失败:所有调用方在同一段时间里一起报错,失败率随调用量均匀分布,日志里 client_ts 和 server_ts 的差值普遍贴着边界。只坏一台则相反——同一套账号、同一份签名代码,其它机器一次不报,这一台隔几小时冒一条,差值忽大忽小。这种局部、间歇、无规律的组合,指向的是单机状态,而不是公共配置。
要说明的是,时间戳在签名里承担的职责很单一:给每个请求一个有效期,把可被原样重放的时间压到很短。防篡改的主力是参数摘要,时间戳只负责回答「这个请求是不是刚刚发出的」。所以时间戳校验失败通常只说明两件事——两端时钟不一致,或者时间格式在某一端被改了。在这类报错里,密钥配错的概率反而靠后。
- 只有时间戳、没有 nonce:窗口内仍可重放,涉及下单、资金的接口要补一次性随机串并落库去重。
- 只有 nonce、没有时间戳:去重记录得长期保留,存储随调用量线性上涨。
- 两者一起用:nonce 只需保留 2 倍窗口,常见区间在 10~20 分钟,过期即可清理。
同样报过期,偏差量级指向不同原因
看差值比看错误文案有用。把客户端时间戳和服务端当前时间各自按 UTC 打出来相减,量级基本就把原因框住了。
- 差值接近整小时(国内常见 8 小时):不是时钟不准,而是一端按本地时区格式化、另一端按 UTC 解析,或带偏移的时间串被截掉了偏移。
- 差值是零散的分秒、且每次都不同:机器时间本身在漂,新加的机器、克隆出来的虚机、长时间休眠的宿主都属于这一类。
- 差值恰好是 1000 倍量级:秒与毫秒没对齐,一端写 13 位、另一端按 10 位解析。
- 时间往回跳、签名变成未来时间:时间源大步校正导致时钟回拨,比过期更难查,日志里往往只留一句校验不通过。
交付时要先钉死一件事:接口文档里写的时间戳是秒还是毫秒、是 UTC 还是带偏移。这两条含糊,后面所有排查都只能靠猜。
排查顺序:先对基准时间,再对格式单位,最后才动窗口
这三段的顺序不能颠倒,因为后一段的结论依赖前一段:窗口调多大,要建立在时钟已对齐、格式已确认的前提上。
- 对基准时间:两端各自同步时间源,打印 UTC 比对,差值收敛到秒级以内再往下走。
- 对格式与单位:确认秒或毫秒、UTC 或带偏移、日期分隔符,以及签名原文的参数排序、空值是否参与、URL 编码次数两端一致。
- 对窗口与 nonce:再决定窗口大小、nonce 保留时长和失败时的错误码划分。
这一步的实际意义是避免用改代码掩盖运维问题。第一段没做就跳到第三段,往往出现窗口越调越大、偶发失败依然存在,而且事后很难回查到底哪一端不准。
窗口配多大:三档可核对的取舍
窗口是可用性与重放风险的折中,没有统一答案,但可以按调用方类型分档,而不是全站一个值。
- 1 分钟以内:适合同机房、时钟由同一套时间源管理、调用频次高的内部服务。对时钟要求苛刻,客户内网稍有漂移就成片失败。
- 3~5 分钟:对接外部客户时的常见区间,能容忍一次时间同步的延迟,nonce 的存储量也可控。
- 10 分钟以上:只在调用方时钟确实不可控、接口本身幂等、且不涉及资金类操作时考虑。窗口越长,nonce 要留越久,可被重放的时间面也越宽。
做到什么程度算够用:日志里能按调用方聚合出 client_ts 与 server_ts 的差值。有了这一项,客户说「就我们一家报错」时,几分钟内就能给出偏差是多少,而不是让对方重启试试。
交付现场:一台漂了十几分钟的机器
在一个总部分散多地的对接项目里,预算紧,没上统一时间源,各分支服务器由本地人员装系统。上线首周签名失败率小幅波动,第一反应是把窗口从 5 分钟调到 30 分钟,结果仍然偶发失败——因为偏差的那台机器已经漂出去十几分钟,放宽窗口只是把失败点往后推。后来改成在网关层把每条失败请求的偏差打点、按调用方聚合,定位到只有一台机器的偏差在持续扩大,单独给它推了内网时间源配置,窗口维持 5 分钟没动。代价是返工了两轮联调,换来的是后面半年没再因这个报错开工单。这类问题的经验区间大致是:偏差在 2 分钟以内,靠把窗口放宽到 5~10 分钟还兜得住;一旦持续超过 10 分钟且还在扩大,调窗口就没意义了,得回到时钟本身。
适用与不适用边界
需要按时间窗校验的,通常是开放的 HTTP 接口、支付与订单类回调、跨公司系统对接。这类场景请求可能被截获并重放,而幂等设计往往只覆盖了部分入口,时间戳加 nonce 的组合是常见做法。
不必上或要谨慎的情况:完全在同一受控内网、调用方固定且已做双向证书认证的服务间调用,可以只验签名不卡时间窗,或把窗口设得很宽;反过来,离线设备、长期断网的终端不适合短窗口,它们的时间天然不可控,更适合用预共享凭证加业务侧幂等来兜。
边界句:时间窗的作用是缩窄可被重放的时间,不是用来弥补时钟不准;任何超过十几分钟的窗口,都应当同时配 nonce 去重和接口幂等。
常见问题
只把窗口从 5 分钟调到 10 分钟,能先顶着上线吗?
可以作为临时兜底,但要同时确认接口幂等和 nonce 去重已就位;窗口翻倍等于可重放的时间翻倍,上线后仍要排时钟同步。
时间戳用秒还是毫秒,有硬性规定吗?
没有统一规定,按对接文档约定即可,关键是两端一致。看到差值恰好是 1000 倍这种量级,先怀疑单位,再怀疑时钟。
客户说服务器不能连外网,对不了时怎么办?
可以让对方接内网时间源,或由我方在响应里带回服务端时间供其自行校正;实在不行才放宽窗口,并把这类调用方单独标记出来。
新加的机器时间看着是对的,为什么还是偶尔失败?
要看偏差方向和漂移速度,不是某一刻的显示值。虚机迁移、宿主休眠后时间步进不补,偏差会在几小时内慢慢累积,只采样一次看不出来。
签名报过期时,先看时间戳还是先看签名串?
先看错误码。服务端能把时间戳过期和摘要不匹配分成两个错误码,一眼就能分流;分不清时先比两端时间戳,再看参数拼接,顺序反了会白查半天。
下次再遇到签名报过期,先别动窗口:把两端 UTC 时间打出来、确认时间戳单位与偏移、再按调用方统计偏差。窗口只是最后一道折中,能对时就别放宽;若对接方环境确实不可控,把窗口大小、nonce 保留时长和接口幂等一起定下来再上线,比事后反复调参省事。
-
客服帮用户重置了密码,用户说旧手机还能直接进,这算重置没成功吗?
日期:2026年11月11日 阅读:35
-
回滚时旧包连新库报字段不存在,直接拿备份把数据库退回去行不行?
日期:2026年11月10日 阅读:43
-
同一句查询早上几十毫秒、下午要好几秒,先查执行计划还是先查锁等待?
日期:2026年11月9日 阅读:36
-
合同附件当天上传还能预览,第二天同事从另一台机器下载却说文件不存在,该先查存储位置还是先查下载接口?
日期:2026年11月8日 阅读:58
-
客户下载的报表名字成了一串 %E4,我们办公室几台电脑都正常,这种只在一台机器冒出来的问题该从哪儿看?
日期:2026年11月7日 阅读:77




