Nginx 中推荐使用内置变量 $msec 配合 map 指令提取整数毫秒时间戳,如 1717023456.123 → 1717023456123;也可用 $time_iso8601 或 $time_local 获取可读字符串;高精度需求需 OpenResty + Lua。

在 Nginx 中无法直接用内置变量动态生成毫秒级时间戳(如 1717023456123),但可以通过组合现有变量 + Lua 模块(OpenResty)或借助系统时间变量实现近似效果。最常用、可靠且无需编译扩展的方式是使用 $msec 变量 —— 它提供秒级精度带三位小数的浮点值(例如 1717023456.123),可格式化为整数毫秒时间戳。
使用 $msec 变量生成毫秒时间戳(推荐,纯 Nginx 原生)
$msec 是 Nginx 内置变量,值为当前时间的 Unix 时间戳(秒)加毫秒小数部分,每次请求独立计算,精度足够用于日志追踪、幂等性辅助、调试标记等场景。
- 直接截取并转为整数毫秒(需配合
map或set+ 正则):
由于 Nginx 配置不支持数学运算,需用 map 提取整数部分和小数部分再拼接:
map $msec $timestamp_ms {
~^(\d+)\.(\d{3}) "$1$2";
default "$msec";
}然后在 location 或 server 块中添加:
proxy_set_header X-Request-Timestamp $timestamp_ms;
这样会把 1717023456.123 转为 1717023456123(13 位毫秒时间戳)。
使用 $time_iso8601 或 $time_local(适合可读时间,非数值计算)
若只需要带时区/本地格式的时间字符串(如 2024-05-30T14:57:36+08:00),可直接使用:
proxy_set_header X-Request-Time-Iso $time_iso8601;proxy_set_header X-Request-Time-Local $time_local;
注意:这些是字符串,不能用于数值比较或排序,但便于人工排查和日志对齐。
进阶:用 OpenResty + Lua 实现任意精度时间戳(如纳秒)
若必须毫秒以上精度(如微秒)、或需自定义格式(含时区偏移、序列号等),建议部署 OpenResty(Nginx + Lua),在 nginx.conf 中启用:
location / {
content_by_lua_block {
local now = ngx.now() -- 秒级浮点
local msec = math.floor(now * 1000) -- 毫秒整数
ngx.req.set_header("X-Request-Timestamp", msec)
ngx.exec("@proxy") -- 跳转到代理逻辑
}
}
location @proxy {
proxy_pass http://backend;
proxy_set_header X-Request-Timestamp $http_x_request_timestamp;
}⚠️ 注意:Lua 方式需安装 OpenResty,且 header 在 Lua 中设置后需透传给后端,不能仅靠 proxy_set_header 直接引用 Lua 变量。
验证与调试技巧
- 用
curl -v查看响应头是否收到该字段; - 后端服务打印接收到的
X-Request-Timestamp,比对是否随每次请求变化; - 在 Nginx 日志中加入
$timestamp_ms,确认格式正确:log_format main '$remote_addr - $timestamp_ms ...';
不复杂但容易忽略的是:确保 map 块放在 http 上下文中(不能在 server 或 location 里),且正则匹配能覆盖所有 $msec 输出格式(通常为 x.xxx 形式)。


















