深入理解tengine的sysguard模块

本文详细介绍了Tengine的Sysguard模块,包括如何开启及配置,以及通过源码分析理解其工作原理。Sysguard提供系统监控,当服务器负载超出预设条件时执行熔断策略,保障系统稳定运行。文章涵盖了模块编译、配置参数、负载指标获取等方面,深入探讨了ngx_http_sysguard_handler函数和各项系统负载如load、CPU使用率、内存的获取方法。
摘要由CSDN通过智能技术生成

1. 引言

  Tengine 是一款高性能的 Web 服务器,其 Sysguard 模块作为其核心功能之一,为用户提供了强大的系统监控和管理能力。通过 Sysguard 模块,用户可以实时监测服务器的运行状态、性能指标和资源利用情况,对异常压力实施熔断处理,从而有效优化系统运行和提升稳定性。本文将深入探讨 Tengine 的 Sysguard 模块,介绍其功能特点、部署配置,以及通过源码分析来深入理解其实现原理。

2. 开启sysguard模块

2.1 编译

  需要开启sysguard模块,因为tengine默认是不加载这个模块的,因此在编译的时候要将这个模块编译进去,如下:


./configure --add-module=modules/ngx_http_sysguard_module

2.2 配置

  直接拿官网文档的例子来举例:


server {
    sysguard on;                   # 开启sysguard模块
    sysguard_mode or;              # 多个负载条件匹配模式采用or还是and方式

    # 格式:负载类型   负载阈值     超过规定阈值后执行的跳转动作目标路径
    # 其中部分指令中定义的period表示性能指标采样的周期
    sysguard_load load=10.5 action=/loadlimit;
    sysguard_cpu usage=20 period=3s action=/cpulimit;
    sysguard_mem swapratio=20% action=/swaplimit;
    sysguard_mem free=100M action=/freelimit;
    sysguard_rt rt=0.01 period=5s action=/rtlimit;

    # 以下几个location定义的是熔断以后,nginx将请求跳转到这里来执行响应处理
    location /loadlimit {
        return 503;
    }

    location /swaplimit {
        return 503;
    }

    location /freelimit {
        return 503;
    }

    location /rtlimit {
        return 503;
    }

    location /cpulimit {
        return 503;
    }
}

  针对上面的范例总结一下,我们可以定义一个或者若干个负载条件(包括load、cpu使用率、内存使用率)采用“与”或者“或”的方式进行组合,当nginx的负载超过了设定的条件的时候,就会执行对应的跳转动作。

  具体的各个配置指令大家可以参考sysguard 模块官方文档

3. 源码分析

3.1 配置参数分析

  首先看一下配置加载的c语言的目标结构体。

typedef struct {
   
    ngx_flag_t                    enable;                 // 是否启用本模块

    ngx_int_t                     load;                   // load阈值
    ngx_str_t                     load_action;            // locad超阈值的跳转地址
    ngx_int_t                     cpuusage;               // cpu使用率阈值
    ngx_str_t                     cpuusage_action;        // cpu使用率超阈值的跳转地址
    ngx_int_t                     swap;                   // swap阈值
    ngx_str_t                     swap_action;            // swap超阈值的跳转地址
    size_t                        free;                   // free内存阈值
    ngx_str_t                     free_action;            // free内存超阈值的跳转地址
    ngx_int_t                     rt;                     // 平均响应时间的阈值
    ngx_int_t                     rt_period;              // 平均响应时间的更新周期
    ngx_str_t                     rt_action;              // 超平均响应时间阈值的跳转地址
    time_t                        interval;               // 获取系统信息时的缓存时间
    time_t                        cpu_interval;           // CPU负载采样更新周期

    ngx_uint_t                    log_level;              // 超阈值事件的日志等级
    ngx_uint_t                    mode;                   // or还是and模式

    ngx_http_sysguard_rt_ring_t  *rt_ring;
} ngx_http_sysguard_conf_t;

  配置加载的时候会根据配置的设置填充以上结构体中对应的字段。

3.2 模块的初始化

  模块的初始化是在ngx_http_sysguard_init函数用执行的。而ngx_http_sysguard_init函数是通过下面的声明来注册到nginx的框架中的。

static ngx_http_module_t  ngx_http_sysguard_module_ctx = {
   
    NULL,                                   /* preconfiguration */
    ngx_http_sysguard_init,                 /* postconfiguration */

    NULL,                                   /* create main configuration */
    NULL,                                   /* init main configuration */

    NULL,                                   /* create server configuration */
    NULL,                                   /* merge server configuration */

    ngx_http_sysguard_create_conf,          /* create location configuration */
    ngx_http_sysguard_merge_conf            /* merge location configuration */
};


ngx_module_t  ngx_http_sysguard_module = {
   
    NGX_MODULE_V1,
    &ngx_http_sysguard_module_ctx,          /* module context */
    ngx_http_sysguard_commands,             /* module directives */
    NGX_HTTP_MODULE,                        /* module type */
    NULL,                                   /* init master */
    NULL,                                   /* init module */
    NULL,                                   /* init process */
    NULL,                                   /* init thread */
    NULL,                                   /* exit thread */
    NULL,                                   /* exit process */
    NULL,                                   /* exit master */
    NGX_MODULE_V1_PADDING
};

  分析ngx_http_sysguard_init函数,我们可以知道,它在NGX_HTTP_PREACCESS_PHASE阶段和NGX_HTTP_LOG_PHASE阶段分别注册了ngx_http_sysguard_handler和ngx_http_sysguard_log_handler两个回调函数,函数定义如下:

static ngx_int_t
ngx_http_sysguard_init(ngx_conf_t *cf)
{
   
    ngx_http_handler_pt        *h;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
    if (h == NULL) {
   
        return NGX_ERROR;
    }

    *h = ngx_http_sysguard_handler;

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
    if (h == NULL) {
   
        return NGX_ERROR;
    }

    *h = ngx_http_sysguard_log_handler;

    return NGX_OK;
}

3.3 ngx_http_sysguard_handler函数

  该函数在NGX_HTTP_PREACCESS_PHASE阶段被调用。
  首先判断本模块是否已经执行过了并且已经被enable了,如果没有enable,则跳过本模块的后续逻辑。

    if (r->main->sysguard_set) {
   
        return NGX_DECLINED;
    }

    glcf = ngx_http_get_module_loc_conf(r, ngx_http_sysguard_module);

    if (!glcf->enable) {
   
        return NGX_DECLINED;
    }

  接着设置sysgaurd_set标记位,表示本模块已经处理过了,后续如果重新进入本函数就不需要重新处理了。

    r->main->sysguard_set = 1;

  为什么会再次进入本函数呢?譬如rewrite操作,或者发生了subrequest请求,都可能导致。

  接下去以load系统负载为例,来看程序的实现逻辑,源码如下:

  /* load */

    if (glcf->load != NGX_CONF_UNSET) {
   

        if (ngx_http_sysguard_cached_load_exptime < ngx_time()) {
   
            ngx_http_sysguard_update_load(r, glcf->interval);
        }

        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "http sysguard handler load: %1.3f %1.3f %V %V",
                       ngx_http_sysguard_cached_load * 1.0 / 1000,
                       glcf->load * 1.0 / 1000,
                       &r->uri,
                       &glcf->load_action);

        if (ngx_http_sysguard_cached_load > glcf->load) {
   

            if (glcf->mode == NGX_HTTP_SYSGUARD_MODE_OR) {
   

                ngx_log_error(glcf->log_level, r->connection
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农心语

您的鼓励是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值