haproxy统计:qtime,ctime,rtime,ttime?

时间:2018-02-12 22:41:18

标签: haproxy metrics latency

在HAProxy 1.6.3-1ubuntu0.1后面运行一个Web应用程序,我的haproxy统计信息qtime,ctime,rtime,ttime值为0,0,0,2704

来自文档(https://www.haproxy.org/download/1.6/doc/management.txt):

 58. qtime [..BS]: the average queue time in ms over the 1024 last requests
 59. ctime [..BS]: the average connect time in ms over the 1024 last requests
 60. rtime [..BS]: the average response time in ms over the 1024 last requests
     (0 for TCP)
 61. ttime [..BS]: the average total session time in ms over the 1024 last requests

我希望响应时间在0-10ms范围内。 2704毫秒的ttime似乎不切实际。单元是否可能关闭,这是2704微秒而不是2704毫秒?

其次,ttime甚至不接近qtime+ctime+rtime似乎很可疑。总响应时间不是排队,连接和响应时间的总和吗?另一次是什么,包含在总数中但不包括队列/连接/响应?为什么我的响应时间<1ms,但我的总响应时间为~2704 ms?

这是我的完整csv统计数据:

$ curl "http://localhost:9000/haproxy_stats;csv"
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime,
http-in,FRONTEND,,,4707,18646,50000,5284057,209236612829,42137321877,0,0,997514,,,,,OPEN,,,,,,,,,1,2,0,,,,0,4,0,2068,,,,0,578425742,0,997712,22764,1858,,1561,3922,579448076,,,0,0,0,0,,,,,,,,
servers,server1,0,0,0,4337,20000,578546476,209231794363,41950395095,,0,,22861,1754,95914,0,no check,1,1,0,,,,,,1,3,1,,578450562,,2,1561,,6773,,,,0,578425742,0,198,0,0,0,,,,29,1751,,,,,0,,,0,0,0,2704,
servers,BACKEND,0,0,0,5919,5000,578450562,209231794363,41950395095,0,0,,22861,1754,95914,0,UP,1,1,0,,0,320458,0,,1,3,0,,578450562,,1,1561,,3922,,,,0,578425742,0,198,22764,1858,,,,,29,1751,0,0,0,0,0,,,0,0,0,2704,
stats,FRONTEND,,,2,5,2000,5588,639269,8045341,0,0,29,,,,,OPEN,,,,,,,,,1,4,0,,,,0,1,0,5,,,,0,5374,0,29,196,0,,1,5,5600,,,0,0,0,0,,,,,,,,
stats,BACKEND,0,0,0,1,200,196,639269,8045341,0,0,,196,0,0,0,UP,0,0,0,,0,320458,0,,1,4,0,,0,,1,0,,5,,,,0,0,0,0,196,0,,,,,0,0,0,0,0,0,0,,,0,0,0,0,

1 个答案:

答案 0 :(得分:0)

在 haproxy >2 中,您现在得到两个值 n / n,即滑动窗口内的最大值和该窗口的平均值。最大值在所有样本窗口中保持最大值,直到找到更高的值。在 1.8 上,您只能获得平均值。

haproxy 2 v 1.8 的示例。请注意,这些代理的使用方式非常不同,负载也大不相同。

haproxy 2.2.8

haproxy 1.8

所以看起来至少自上次重启以来的平均响应时间是 66m 和 275ms。

平均值计算如下:

data time + cumulative http connections - 1 / cumulative http connections

这可能不是一个完美的分析,所以如果有人有改进,我们将不胜感激。这是为了展示我如何得出上述答案,以便您可以使用它来更深入地了解您询问的其他计数器。大部分信息是从阅读stats.c 中收集的。您询问的计数器定义为 here

unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
unsigned int qtime_max, ctime_max, dtime_max, ttime_max; /* maximum of conn_time, queue_time, data_time, total_time observed */```

统计页面的值是根据以下代码构建的:

if (strcmp(field_str(stats, ST_F_MODE), "http") == 0)
            chunk_appendf(out, "<tr><th>- Responses time:</th><td>%s / %s</td><td>ms</td></tr>",
                      U2H(stats[ST_F_RT_MAX].u.u32), U2H(stats[ST_F_RTIME].u.u32));
            chunk_appendf(out, "<tr><th>- Total time:</th><td>%s / %s</td><td>ms</td></tr>",
                  U2H(stats[ST_F_TT_MAX].u.u32), U2H(stats[ST_F_TTIME].u.u32));   

您询问了所有柜台,但我将重点介绍一个。从上面的“响应时间”片段可以看出:ST_F_RT_MAXST_F_RTIME 分别是在统计页面上显示为 n (rtime_max) / n (rtime) 的值。这些定义如下:

[ST_F_RT_MAX] = { .name = "rtime_max", .desc = "Maximum observed time spent waiting for a server response, in milliseconds (backend/server)" },
[ST_F_RTIME] = { .name = "rtime", .desc = "Time spent waiting for a server response, in milliseconds, averaged over the 1024 last requests (backend/server)" },

这些在代码更下方的 case 语句中设置了一个“度量”值(除其他外):

case ST_F_RT_MAX:
    metric = mkf_u32(FN_MAX, sv->counters.dtime_max);
    break;
case ST_F_RTIME:
    metric = mkf_u32(FN_AVG, swrate_avg(sv->counters.d_time, srv_samples_window));
    break;

这些指标值让我们可以很好地了解统计信息页面告诉我们的内容。 “响应时间:0 / 0”ST_F_RT_MAX 中的第一个值是一些最大值 等待时间。 “响应时间:0 / 0ST_F_RTIME 中的第二个值是每次连接所用的平均时间。这些是一段时间内的最大值和平均值,即获得 1024 个连接需要多长时间。

例如“响应时间:10000 / 20”:

  • 在过去 1024 个连接 10 秒内花费的最大等待时间(曾经达到的最大值,包括 http keepalive 时间)
  • 过去 1024 个连接的平均时间为 20 毫秒

所以出于所有意图和目的

rtime_max = dtime_max
rtime = swrate_avg(d_time, srv_samples_window)

这引出了一个问题,dtime_max d_timesrv_sample_window 是什么?这些是数据时间窗口,我实际上无法弄清楚这些时间值是如何设置的,但从表面上看,它是最后 1024 个连接的“一段时间”。正如所指出的,here 保持活动时间包含在最大总数中,这就是为什么数字很高。

既然我们知道 ST_F_RT_MAX 是最大值,而 ST_F_RTIME 是平均值,那么平均值是多少?

/* compue time values for later use */
if (selected_field == NULL || *selected_field == ST_F_QTIME ||
    *selected_field == ST_F_CTIME || *selected_field == ST_F_RTIME ||
    *selected_field == ST_F_TTIME) {
    srv_samples_counter = (px->mode == PR_MODE_HTTP) ? sv->counters.p.http.cum_req : sv->counters.cum_lbconn;
    if (srv_samples_counter < TIME_STATS_SAMPLES && srv_samples_counter > 0)
        srv_samples_window = srv_samples_counter;
}

TIME_STATS_SAMPLES 值定义为

#define TIME_STATS_SAMPLES 512
unsigned int srv_samples_window = TIME_STATS_SAMPLES;

在模式 http srv_sample_countersv->counters.p.http.cum_reqhttp.cum_req 定义为 ST_F_REQ_TOT

[ST_F_REQ_TOT]  = { .name = "req_tot",  .desc = "Total number of HTTP requests processed by this object since the worker process started" },

例如,如果 http.cum_req 的值为 10,则 srv_sample_counter 将为 10。示例似乎是给定后端服务器的给定示例窗口的成功请求数。 d_time(数据时间)作为“总和”传递,并计算为某个非负值或计为错误。我以为我找到了如何创建 d_time 的代码,但我不确定所以我没有包含它。

/* Returns the average sample value for the sum <sum> over a sliding window of
 * <n> samples. Better if <n> is a power of two. It must be the same <n> as the
 * one used above in all additions.
 */
static inline unsigned int swrate_avg(unsigned int sum, unsigned int n)
{
    return (sum + n - 1) / n;
}