Inconsistent time measurement in Nginx

Maxim Dounin mdounin at mdounin.ru
Tue Sep 28 13:44:16 UTC 2021


Hello!

On Tue, Sep 28, 2021 at 10:27:55AM +0800, Zexuan Luo wrote:

> Hi, Nginx developers:
> 
> Currently, the request_time uses ngx_timeofday to get the time, which
> finally will call gettimeofday. Meanwhile, the upstream_x_time series
> uses ngx_current_msec to calculate the time, which finally will call
> ngx_monotonic_time.
> 
> On Linux, the gettimeofday will call clock_gettime(CLOCK_REALTIME,
> &ts) while the ngx_monotonic_time will call
> clock_gettime(CLOCK_MONOTONIC_COARSE, &ts).
> 
> So the request_time uses CLOCK_REALTIME and the upstream_x_time series
> uses CLOCK_MONOTONIC_COARSE. As they are different sources, sometimes
> we observe that the upstream_response_time is larger than
> request_time. This behavior is unexpected and has caused bug in our
> software.
> 
> A similar report can be also found in
> https://stackoverflow.com/questions/53978695/how-can-request-time-be-less-than-upstream-response-time-in-nginx.
> 
> Is this behavior intended? Why not use the same time measurement for
> all metrics? Thanks for your reply.

The $upstream_response_time variable was changed to use 
ngx_current_msec in 59fc60585f1e 
(http://hg.nginx.org/nginx/rev/59fc60585f1e) as part of 
$upstream_connect_time introduction, because it is easier to code 
and more appropriate for time interval measurements, especially 
following introduction of CLOCK_MONOTONIC usage.

The $response_time still uses ngx_timeofday() for mostly historic 
reasons.  Likely it will be changed to use ngx_current_msec, 
though this needs to be done with care, notably because 
ngx_current_msec can overflow on 32-bit platforms.  At some point 
there was a patch by Sergey Kandaurov to do the change, though it 
was postponed due to questions on what happens on overflows in 
limit_rate handling.

-- 
Maxim Dounin
http://mdounin.ru/


More information about the nginx-devel mailing list