Nginx的server块listen命令详解

深入理解 Python 中的 `server.listen(backlog)`:监听队列的奥秘 是一个重要的方法,用于设置服务器套接字的监听状态和最大未完成连接数。backlog参数决定了服务器可以同时处理的最大未完成连接数。通过合理设置backlog的值,可以优化服务器的性能和资源利用率。希望本文能帮助你更好地理解的作用和使用方法。如果你有任何疑问或建议,欢迎在评论区留言。 阅读详情

看到了后面才发现其实自己在server块命令这一部分并没有搞的太清楚,因而会影响到以后对代码的理解,因而从头又来看一遍,一定要把它搞明白。

首先我们来看ngx_http_core_module的main_conf结构:

typedef struct {
	 /** 
     * 存储所有的ngx_http_core_srv_conf_t,元素的个数等于server块的个数。 ,因为同一个http块命令可以配置多个server
     */  
    ngx_array_t                servers;         /* ngx_http_core_srv_conf_t */

	/** 
	  * 包含所有phase,以及注册的phase handler,这些handler在处理http请求时, 
	  * 会被依次调用,通过ngx_http_phase_handler_t的next字段串联起来组成一个 
	  * 链表。 
	  */  
    ngx_http_phase_engine_t    phase_engine;

    /** 
     * 以hash存储的所有request header 
     */  
    ngx_hash_t                 headers_in_hash;

    /** 
     * 被索引的nginx变量 ,比如通过rewrite模块的set指令设置的变量,会在这个hash 
     * 中分配空间,而诸如$http_XXX和$cookie_XXX等内建变量不会在此分配空间。 
     */  
    ngx_hash_t                 variables_hash;

    /** 
     * ngx_http_variable_t类型的数组,所有被索引的nginx变量被存储在这个数组中。 
     * ngx_http_variable_t结构中有属性index,是该变量在这个数组的下标。 
     */  
    ngx_array_t                variables;       /* ngx_http_variable_t */
    ngx_uint_t                 ncaptures;

    /** 
     * server names的hash表的允许的最大bucket数量,默认值是512。 
     */  
    ngx_uint_t                 server_names_hash_max_size;
    ngx_uint_t                 server_names_hash_bucket_size;

    ngx_uint_t                 variables_hash_max_size;
    ngx_uint_t                 variables_hash_bucket_size;

    ngx_hash_keys_arrays_t    *variables_keys;

	/** 
	   * 监听的所有端口,ngx_http_conf_port_t类型,其中包含socket地址信息。 
	   */  
    ngx_array_t               *ports;  //保存ngx_http_conf_port_t结构的元素,在ngx_http_optimize_servers函数中,将会用到ports中的元素来创建监听

    ngx_uint_t                 try_files;       /* unsigned  try_files:1 */
	
    /** 
     * 所有的phase的数组,其中每个元素是该phase上注册的handler的数组。 
     */  
    ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1];
} ngx_http_core_main_conf_t;
其有几个比较重要的域是:

(1)servers,因为整个http块命令中创建的配置结构的main_conf结构都是统一的,但是同一个http块命令中却可以配置多个server块命令,servers数组就是用来保存这些独立的server块配置的,其保存的没一个元素都是ngx_http_core_srv_conf_t类型的。

(2)ports,其也是一个数组,我们在listen指令中会指定监听的地址端口的信息,由于可能会同时监听多个,所以ports数组就用来保存所有的这些监听的信息,在listen指令的回调函数中会将这些配置信息保存到ports数组中,其中保存的元素是ngx_http_conf_port_t结构,而且最后会调用ngx_http_optimize_servers函数来根据其中保存的信息来生成最后的ngx_listening_t结构。

接下来我们来看ngx_http_core_module模块的srv_conf结构:

typedef struct {
    /* array of the ngx_http_server_name_t, "server_name" directive */
    ngx_array_t                 server_names;  //server的名字数组   ngx_http_server_name_t

    /* server ctx */
    ngx_http_conf_ctx_t        *ctx;  // 指向包含它的ngx_http_conf_ctx_t结构,因为在server块命令的回调函数中会重新创建ngx_http_conf_ctx_t结构,但是其中的main_conf结构都是统一的

    ngx_str_t                   server_name;  //名字

    size_t                      connection_pool_size;  //connection池的大小
    size_t                      request_pool_size;
    size_t                      client_header_buffer_size;

    ngx_bufs_t                  large_client_header_buffers;

    ngx_msec_t                  client_header_timeout;   //请求超时时间

    ngx_flag_t                  ignore_invalid_headers;
    ngx_flag_t                  merge_slashes;
    ngx_flag_t                  underscores_in_headers;

    unsigned                    listen:1;  //区别当前server是否监听
#if (NGX_PCRE)
    unsigned                    captures:1;
#endif

    ngx_http_core_loc_conf_t  **named_locations;  //该srv配置的location配置数组
} ngx_http_core_srv_conf_t;
其中有几个比较重要的域:

(1)ctx,我们已经知道在每一个server块命令中都会重新创建ngx_http_conf_ctx_t结构,它的main_conf中的数据都是统一的,ctx就是用来指向当前server块命令中自己创建的ngx_http_conf_ctx_t结构。

(2)listen:如果在当前server块命令中配置了listen指令,那么它的值将会设置为1,否则的话就代表没有配置listen指令,那么ngx就必须为当前server设置默认的监听信息,默认为80端口和所有ip地址。

(3)named_locations:其是一个动态数组,用来保存location的一些配置信息。


好了,接下来我们来看server命令的回调函数(ngx_http_core_server):

    ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));   //为配置上下文分配内存空间,这里之所以要重新创建新的ngx_http_conf_ctx_t配置结构,是为了处理同时会有好几个server的情况,但是这些创建的ngx_http_conf_ctx_t结构的main_conf都是统一的
    if (ctx == NULL) {
        return NGX_CONF_ERROR;
    }

    http_ctx = cf->ctx;
    ctx->main_conf = http_ctx->main_conf;  //这里用当前刚刚创建的配置上下文的main_conf指向以前的main_conf,这样可以保证main_conf的统一,因为main_conf只有一个
首先就是重新创建ngx_http_conf_ctx_t结构,然后将其的main_conf中的数据设置为上一级ngx_http_conf_ctx_t结构中的main_conf,说白了就是在http块命令中创建的main_conf ,这也就保证了mian_conf的统一。
//创建当前server块的srv_conf的内存空间,因为同一个http里面可能会有多个server命令,因而要为每一个server指令都给所有的http模块进行配置
    ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    if (ctx->srv_conf == NULL) {
        return NGX_CONF_ERROR;
    }

    /* the server{}'s loc_conf */
//为当前server指令内的loc_conf分配内存
    ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    if (ctx->loc_conf == NULL) {
        return NGX_CONF_ERROR;
    }
//还是因为有多个server的存在,所以这里要继续要为每一个模块创建srv_conf与loc_conf
    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
            continue;
        }

        module = ngx_modules[i]->ctx;

        if (module->create_srv_conf) {
            mconf = module->create_srv_conf(cf);  //重新创建http模块的srv_conf结构
            if (mconf == NULL) {
                return NGX_CONF_ERROR;
            }

            ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
        }

        if (module->create_loc_conf) {
            mconf = module->create_loc_conf(cf);   //重新创建http模块的loc_conf
            if (mconf == NULL) {
                return NGX_CONF_ERROR;
            }

            ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
        }
    }
接下来的代码就是为刚刚创建的ngx_http_conf_ctx_t结构重新分配srv_conf以及loc_conf 的内存空间,并调用http模块的相应的函数来初始化它们。
    cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];   //得到刚刚为ngx_http_core_module模块创建的server配置结构ngx_http_core_srv_conf_t
    cscf->ctx = ctx;  //将当前ngx_http_core_module模块创建的srv_conf结构的ctx指针指向当前创建的ngx_http_conf_ctx_t结构
    

    cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];  //获取ngx_http_core_module的main_conf,它有一个servers数组,用来保存所有的server配置项,这里要知道的是main_conf 只有一个

    cscfp = ngx_array_push(&cmcf->servers);  //将刚刚创建的创建的ngx_http_core_module的srv_conf结构,即ngx_http_core_srv_conf_t结构保存入ngx_http_core_module模块的main_conf里面的servers数组当中
    if (cscfp == NULL) {
        return NGX_CONF_ERROR;
    }

    *cscfp = cscf;  //赋值,这里相当于是真正的压入到数组当中去
接下来的代码首先获取刚刚创建的ngx_http_core_srv_conf_t结构,并将其的ctx域指向刚刚创建的ngx_http_conf_ctx_t结构,接着在获取ngx_http_core_main_conf_t结构,由前面的说明我们已经知道这个结构是唯一的,然后将刚刚创建的ngx_http_core_srv_conf_t保存到ngx_http_core_main_conf_t的servers数组当中去。
    pcf = *cf;  //这里还是备份cf结构,然后准备解析server块命令,这里之所以备份,是因为ngx_conf_parse函数式递归调用了,为了内层的不影响外层的
    cf->ctx = ctx;  //相当于是把新创建的配置向下文传入解析函数
    cf->cmd_type = NGX_HTTP_SRV_CONF;     //表示要解析的命令的类型

    rv = ngx_conf_parse(cf, NULL); //开始解析server块命令,这里面还涉及到location指令

    *cf = pcf;
接下来的代码就开始调用ngx_conf_parse函数来继续解析server块里面的命令了。
if (rv == NGX_CONF_OK && !cscf->listen) {   //表示当前所属的server块命令并没有用listen指令来申明监听端口,那么nginx会安排一个默认的监听,80端口
        ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));

        sin = &lsopt.u.sockaddr_in;

        sin->sin_family = AF_INET;
#if (NGX_WIN32)
        sin->sin_port = htons(80);  //默认80端口
#else
        sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
#endif
        sin->sin_addr.s_addr = INADDR_ANY;  //接收任意网卡连接

        lsopt.socklen = sizeof(struct sockaddr_in);

        lsopt.backlog = NGX_LISTEN_BACKLOG;
        lsopt.rcvbuf = -1;
        lsopt.sndbuf = -1;
#if (NGX_HAVE_SETFIB)
        lsopt.setfib = -1;
#endif
        lsopt.wildcard = 1;

        (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
                             NGX_SOCKADDR_STRLEN, 1);

        if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {  //调用ngx_http_add_listen方法加入监听socket
            return NGX_CONF_ERROR;
        }
    }
最后的代码就是判断当前server块命令是否配置了listen命令,如果没有的话那么就需要为它安排默认的监听结构信息。

接下来我们来看listen命令的回调函数(ngx_http_core_listen):

    cscf->listen = 1;  //表示当前的server配置已经进行了listen配置,如果不listen配置的话,那么会安排默认的端口监听

    value = cf->args->elts;  //获取解析出来的参数

    ngx_memzero(&u, sizeof(ngx_url_t));
 
    u.url = value[1];     //获取传进来的地址(ip+port)
    u.listen = 1;
    u.default_port = 80; //默认端口

    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {   //相当于是对u进行初始化,比如说ip地址,端口号等
        if (u.err) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "%s in \"%V\" of the \"listen\" directive",
                               u.err, &u.url);
        }

        return NGX_CONF_ERROR;
    }
首先是将当前server块的配置结构的listen域设置为1,表示当前server已经设置了监听,然后获取传进来的地址,也就是ip+port的字符串,然后用其来初始化ngx_url_t结构,解析出ip地址端口号等。
    ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));  //清零监听配置结构

    ngx_memcpy(&lsopt.u.sockaddr, u.sockaddr, u.socklen);  //为lsopt的地址结构赋值
//初始化监听套接字的配置
    lsopt.socklen = u.socklen;  //socket地址结构的长度
    lsopt.backlog = NGX_LISTEN_BACKLOG;
    lsopt.rcvbuf = -1;   //接收缓冲
    lsopt.sndbuf = -1;
#if (NGX_HAVE_SETFIB)
    lsopt.setfib = -1;
#endif
    lsopt.wildcard = u.wildcard;

//将二进制的地址结构转换为文本的形式
    (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
                         NGX_SOCKADDR_STRLEN, 1);
然后根据地址信息来初始化监听结构ngx_http_listen_opt_t,接下来就是再根据listen指令传进来的其他的参数来初始化ngx_http_listen_opt_t结构,例如是否是default_server等。
    if (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {   //加入监听套接字,将会创建ngx_http_conf_port_t结构,并将其放入到ngx_http_core_main_conf_t的ports数组当中
        return NGX_CONF_OK;
    }
最后调用ngx_http_add_listen函数根据ngx_http_listen_opt_t来创建ngx_http_conf_port_t结构,并将其保存到ngx_http_core_main_conf_t结构的ports数组当中。

接下来我们来看ngx_http_add_listen函数:

 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);  //获取ngx_http_core_module的main_conf 配置结构,这个配置结构是保持统一的
//初始化ngx_http_core_module的ports数组
    if (cmcf->ports == NULL) {  //如果其ports的数组还没有初始化
        cmcf->ports = ngx_array_create(cf->temp_pool, 2,
                                       sizeof(ngx_http_conf_port_t));
        if (cmcf->ports == NULL) {
            return NGX_ERROR;
        }
    }
//获取网际地址结构
    sa = &lsopt->u.sockaddr;
//判断地址结构的类型
    switch (sa->sa_family) {

#if (NGX_HAVE_INET6)
    case AF_INET6:
        sin6 = &lsopt->u.sockaddr_in6;
        p = sin6->sin6_port;
        break;
#endif

#if (NGX_HAVE_UNIX_DOMAIN)
    case AF_UNIX:
        p = 0;
        break;
#endif

    default: /* AF_INET */
        sin = &lsopt->u.sockaddr_in;  //获取IPV4地址结构
        p = sin->sin_port;  //获取端口号
        break;
    }
首先是获取ngx_http_core_main_conf_t结构,判断其的ports数组是否初始化,如果没有的话那么要对其进行初始化。然后根据传进来的ngx_http_listen_opt_t结构,获取地址以及端口等信息。
    port = cmcf->ports->elts;
	//遍历ports数组,看要添加的端口号信息是否存在,如果已经存在的话,调用ngx_http_add_addresses函数将相应的地址信息加入到port上就可以的
	//也就是要判断以前是否已经在该端口上进行了listen,如果有的话那么只需要给该端口再加上一个地址结构就可以了
    for (i = 0; i < cmcf->ports->nelts; i++) {

        if (p != port[i].port || sa->sa_family != port[i].family) {
            continue;
        }

        /* a port is already in the port list */
//如果端口的信息已经存在于ports数组当中了,那么只需要添加一个地址结构就可以了
        return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
    }
	
接下来就是便利ports数组中的所有元素,判断是否在同一个端口已经配置了监听信息,如果有的话,那么只需要调用ngx_http_add_addresses函数在其的ngx_http_conf_port_t结构上加入一个地址记性了。
 port = ngx_array_push(cmcf->ports);
    if (port == NULL) {
        return NGX_ERROR;
    }
//相当于是为刚刚压入数组的元素赋值
    port->family = sa->sa_family;
    port->port = p;   //端口号
    port->addrs.elts = NULL;  //将addres数组置空
//添加地址信息
    return ngx_http_add_address(cf, cscf, port, lsopt);  //为该端口添加地址结构
如果没有的话,那么就需要在ports数组中新建一个ngx_http_conf_port_t结构,并初始化其的一些基本信息,最后调用ngx_http_add_address为其添加地址结构。

我们首先来看ngx_http_add_addresses函数吧,它表示在当前端口已经配置了监听信息了,那么就只需要为其添加一些地址信息就可以了:

 addr = port->addrs.elts;

	/** 
	 * 在port的addr数组中已经存在该地址时,直接将ngx_http_core_srv_conf_t 
	 * 结构添加到到addr对应的servers数组中。 
	 */  
    for (i = 0; i < port->addrs.nelts; i++) {
  //比较地址是否相同
        if (ngx_memcmp(p, addr[i].opt.u.sockaddr_data + off, len) != 0) {
            continue;
        }

        /* the address is already in the address list */
//将当前的ngx_http_core_srv_conf_t直接压入到addr的servers数组中就行了
        if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
            return NGX_ERROR;
        }

        /* preserve default_server bit during listen options overwriting */
        default_server = addr[i].opt.default_server;

#if (NGX_HTTP_SSL)
        ssl = lsopt->ssl || addr[i].opt.ssl;
#endif

        if (lsopt->set) {

            if (addr[i].opt.set) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                        "duplicate listen options for %s", addr[i].opt.addr);
                return NGX_ERROR;
            }

            addr[i].opt = *lsopt;
        }

        /* check the duplicate "default" server for this address:port */

        if (lsopt->default_server) {  //当前监听配置结构的server配置结构为默认server

            if (default_server) {   //如果已经设置了默认server,那么就表示同一个地址上设置了多个默认server,那么可以报错了
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                        "a duplicate default server for %s", addr[i].opt.addr);
                return NGX_ERROR;
            }

            default_server = 1;
            addr[i].default_server = cscf;  //将该地址的默认server设置为当前的server配置结构
        }

        addr[i].opt.default_server = default_server; //表示已经有默认server配置信息了
#if (NGX_HTTP_SSL)
        addr[i].opt.ssl = ssl;
#endif

        return NGX_OK;
    }

    /* add the address to the addresses list that bound to this port */
//表示在当前端口并没有同样的地址监听,那么需要为当前端口新加入一个地址监听
    return ngx_http_add_address(cf, cscf, port, lsopt);
函数根据当前的ngx_http_conf_port_t的addrs数组中的信息来判断在当前端口上是否有相同的地址在监听,如果有的话那么就只需要为其(ngx_http_conf_addr_t)添加一个server配置结构就可以了,然后在判断一些default的信息来初始化,否则的话还是需要调用ngx_http_add_address函数来为当前的ngx_http_conf_port_t结构加入新的监听地址。

接下来我们来看ngx_http_add_address:

static ngx_int_t
ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
    ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)
{
    ngx_http_conf_addr_t  *addr; //创建一个地址配置结构
//如果当前的port配置结构的addrs数组为空,那么初始化它
    if (port->addrs.elts == NULL) {
        if (ngx_array_init(&port->addrs, cf->temp_pool, 4,
                           sizeof(ngx_http_conf_addr_t))
            != NGX_OK)
        {
            return NGX_ERROR;
        }
    }

    addr = ngx_array_push(&port->addrs);   //压入ngx_http_conf_port_t结构的addrs数组当中
    if (addr == NULL) {
        return NGX_ERROR;
    }
//为压入的地址结构赋值 
    addr->opt = *lsopt;   //监听配置结构,包含了地址地址等信息
    addr->hash.buckets = NULL;
    addr->hash.size = 0;
    addr->wc_head = NULL;
    addr->wc_tail = NULL;
#if (NGX_PCRE)
    addr->nregex = 0;
    addr->regex = NULL;
#endif
    addr->default_server = cscf;   //设置默认的server,将当前的server配置结构设置为当前地址监听的默认server,因为调用ngx_http_add_address函数代表是第一次加入该地址监听
    addr->servers.elts = NULL;

    return ngx_http_add_server(cf, cscf, addr);  //该函数用于将当前的ngx_http_core_srv_conf_t结构压入到地质结构addr的servers数组中,表示当前的地址结构增加一个server配置结构
}
该函数相对比较简单,首先判断ngx_http_conf_port_t结构的addrs数组是否已经初始化了,然后在向addrs数组中压入一个ngx_http_conf_addr_t结构就可以了,然后对其进行一些初始化,最后在调用ngx_http_add_server函数向刚创建的ngx_http_conf_addr_t结构中加入一个ngx_http_core_srv_conf_t配置结构就可以了。

接下来我们来看ngx_http_add_server函数:

static ngx_int_t
ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
    ngx_http_conf_addr_t *addr)
{
    ngx_uint_t                  i;
    ngx_http_core_srv_conf_t  **server;
//初始化地址结构的servers数组
    if (addr->servers.elts == NULL) {
        if (ngx_array_init(&addr->servers, cf->temp_pool, 4,
                           sizeof(ngx_http_core_srv_conf_t *))
            != NGX_OK)
        {
            return NGX_ERROR;
        }

    } else {
        server = addr->servers.elts;
        for (i = 0; i < addr->servers.nelts; i++) {    
            if (server[i] == cscf) {  //表示为同一个地址监听设置了两次相同的server配置结构,那么就出错了
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                   "a duplicate listen %s", addr->opt.addr);
                return NGX_ERROR;
            }
        }
    }

    server = ngx_array_push(&addr->servers);  //压入数组
    if (server == NULL) {
        return NGX_ERROR;
    }

    *server = cscf; // 赋值

    return NGX_OK;
}
这个函数还是很简单的,说白了就是为ngx_http_conf_addr_t结构的servers数组中添加一个ngx_http_core_srv_conf_t结构就可以了。

根据上面的信息我们就可以知道通过listen指令实际上是将信息组织成了如下的形式:


Nginx server块与location块匹配算法详解 Nginx虚拟主机路由与URI路径匹配是Web服务器配置的核心机制。其本质是基于TCP监听、HTTP Host头/SNI域名解析的server块选择,以及遵循精确匹配>前缀匹配>正则匹配的七步location决策树。该机制决定了请求如何被精准分发到对应服务单元,直接影响HTTPS证书加载、静态资源404、API网关转发等关键行为。理解server_name匹配优先级、listen指令隐式协议约束、location ^~与~的冲突规则,是实现高可用反向代理、安全路径控制和可验证配置落地的技术基础。本文深入剖析 阅读详情

相关推荐

Nginx server块与location匹配机制深度解析

Nginx的请求路由并非负载均衡或动态调度,而是一套基于编译期构建的确定性匹配引擎。其核心原理是:server块选择依赖listen地址三元组(IP:端口:SSL)哈希索引与server_name精确哈希查找;location匹配则严格遵循最长字面量前缀优先原则,正则仅作兜底且按配置顺序线性扫描。该机制具有零运行时随机性、毫秒级确定性、强可预测性等技术价值,广泛应用于高可用Web网关、API路由、静态资源分发等场景。理解这一底层匹配逻辑,是解决404/502故障、规避alias/root陷阱、优化locat

weixin_33933118的博客 560

nginx配置之server

nginx配置之server

运维@小兵的博客 1万+

Field-Oriented Control (FOC) 矢量控制 磁场定向控制

Field-Oriented Control (FOC) 磁场定向控制(FOC),也称为矢量控制,是一种用于控制永磁同步电动机(PMSM)和交流感应电动机(ACIM)的技术。 FOC在整个扭矩和速度范围内都具有良好的控制能力。 FOC的实现需要将定子电流从固定参考系转换为转子磁通参考系(也称为d-q参考系)。 速度控制和转矩控制是FOC最常用的控制模式。位置控制模式不太常见。大多数牵引应用使用转矩控制模式,在该模式下,电动机控制系统遵循参考转矩值。在速度控制模式下,电机控制器遵循参考速度值,并生成用于形成内

>>> 1万+

NGINX源码之:listen和server_name命令与listening监听创建

nginx listen命令,server_name命令解析,ngx_http_core_listen()、ngx_parse_url()、ngx_http_add_listen()、ngx_http_optimize_servers()、ngx_http_server_names()、ngx_http_init_listening()等方法解读

qq_22351805的博客 3754

labview中DAQ采集多个数据通道(温度传感器)(TTL信号的曲轴位置传感器)总结

文章目录前言一、面对的问题篇二、问题解决篇三、后续工作总结 前言 我研一的项目利用labview软件和NI数据采集卡采集发动机传感器的信号然后进行采集,发动机传感器是有很多种的,所以难以避免的需要采集多个通道的传感器信号。 一、面对的问题篇 前篇已经写道我已经将温度传感器的信号采集出来,也可以将其数据进行信号处理,由电压信号转变为温度值。但是想要采集多个通道的信号,加上TTL信号的曲轴位置传感器,我模仿温度传感器采集的程序另加了一个DAQ助手进行采集。也就是如图所示的程序: 但是这个程序不能正常显

xiaobaiwsc的博客 1万+

【RT-DETR多模态融合改进】| 自研 多模态大核选择模块:MM_LSK,适配多模态图像信息融合

本文记录的利用改进的多模态大核选择模块(MM-LSK)优化RT-DETR,构建可见光-红外双模态目标检测网络。在遥感等大尺寸图像的可见光-红外双模态小目标检测任务中,单模态检测易受光照、云雾、背景干扰等因素影响,且小目标外观信息匮乏,无法仅基于单模态外观实现较好的识别,因此需要融合双模态互补特性与广泛的跨模态上下文信息进行辅助。

Limiiiing的博客 381

【浅】nginx.conf 配置之listen、server_name

关于虚拟主机server 的 listen 、server_name 配置: listen 对应nginx虚拟主机对外提供服务的端口 server_name 可以理解成虚拟主机的名字,这个值会和http请求里的Host header做匹配 所以在同一个nginx.conf配置文件里,只要 listen 、server_name组合起来唯一就没有问题; server_name 这一行可以配置多个,中间用空格隔开,例如: server { listen 80;

万物皆字节 5111

MathType公式使用技巧汇总——Mathtype怎么在word中编辑公式?论文中公式有哪技巧?有哪些注意事项?论文中的公式怎么写?

如果word中到公式编号(2-1)中间的符号如下图........ .......类似与省略号的,这是手动打的空格,公式和编号的位置都是手动敲空格操作的,这种就只是使用MathType写了公式而已,格式上还是很不方便的。**如果要修改公示,直接双击文档中的公式,就会自动弹出MathType公式编辑窗口,进行修改。如果要修改公示,直接双击文档中的公式,就会自动弹出MathType公式编辑窗口,进行修改。而第二种,是公式里面带的括号符号,他是可以随着公式结构自适应变化的。这时需要将公式插入到一行文字的某处,

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 5万+

Nginx - server、listen、server_name和多服务请求处理(三)

Nginx如何处理多服务请求

幻世 963

使用CUDA进行按流排序的内存分配的示例程序

在GPU编程中,按流排序的内存分配是一种常见的优化技术,它可以提高内存访问的效率。通过将内存分配与特定的CUDA流相关联,可以确保在GPU上的并发操作期间,内存分配操作与其他GPU计算操作同时进行,从而减少了潜在的内存访问延迟。请注意,上述示例中的代码仅供参考,并可能需要根据实际需求进行修改和调整。此外,为了完整性,我们省略了一些细节,例如主机指针的分配和释放,以及错误处理和错误检查等。在该示例中,我们创建了4个CUDA流,并使用内存池进行内存分配。然后,我们在每个流上执行了相应的内存访问操作,并使用。

Byte_O_O的博客 281

【ARM CoreLink 系列 4 -- NIC-400 控制器详细介绍】

正常情况下,一个NIC的实现,可以包含一百多个master和几十个slave,每个master和每个slave都会有一些寄存器,这些寄存器可以被 programming,实际实践中就会对 AMIB 或者 ASIB 或者 IB,当它需要具有 programming的时候,给它指定一个node number。为什么指定Node Number呢?首先,从CPU的角度,它需要有一个1M对齐的地址空间,在这1M地址空间上,对每个ASIB或者AMIB这样的接口给它一个node number以后,

CodingCos的博客 5241

nginx 配置文件详解以及示例

本文详细介绍了Nginx的各个配置项和一个完整的示例配置。

欢迎来到橙子家的博客。 4684

WIN10系统下VS2019编译CloudCompare2.12.4

CloudCompare2.12.4

点云侠的博客 3143

对于nginx配置中listen 和server_name 的理解

当nginx接到请求后,会匹配其配置中的service模块, 匹配方法就是靠请求携带的host和port正好对应其配置中的server_name 和listen。 如果做过ip和域名绑定,ip和域名二者是对等的 比如: server { listen 8080; server_name www.abc.com; access_log /...

chen的专栏 11万+

YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml

全网最详细的YOLOv5源码解读之配置文件yaml。逐行注释,逐句讲解,一文带你了解yaml。小白必看!

路人贾的博客 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

nginx之listen命令入门

listen命令是 Nginx 配置中的关键指令,用于定义服务器监听的地址和端口,并支持多种参数以优化性能和功能。

鸭梨的博客 1502

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Nginx基本配置文件详解

Nginx基本配置文件详解

bjzhang75的博客 3371

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Nginx中的server块和location块详解

default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port,则会默认执行的。由于server_name指令支持通配符和正则表达式,因此在包含多个虚拟主机的配置文件中,可能会出现一个名称被多个虚拟主机的server_name匹配成功,当遇到这种情况,当前的请求交给谁来处理呢?No5:被默认的default_server处理,如果没有指定默认找第一个server。server_name:用来设置虚拟主机服务名称。

· 1496

nginx配置文件详解

nginx配置文件

糖果贩子的博客 5198

Nginx 多端口监听 3 种配置模式对比:单Server块 vs 多Server块 vs 端口映射

本文深入对比了Nginx多端口监听的三种配置模式:单Server块多端口、多Server块独立端口和端口映射。通过详细解析每种模式的实现方法、核心特点及适用场景,帮助开发者根据实际需求选择最佳方案,优化Web服务器性能与安全性。

weixin_30417487的博客 436

Nginx配置详解

location块的主要作用是,基于Nginx服务器接收到的请求字符串(例如, server_name/uri-string),对除虚拟主机名称(也可以是IP别名,后文有详细阐述)之外的字符串(前例中“/uri-string”部分)进行匹配,对特定的请求进行处理。前面已经提到,http块中可以包含自己的全局块,也可以包含server块,server块中又可以进一步包含location块,在本书中我们使用“http全局块”来表示http中自己的全局块,即http块中不包含在server块中的部分。

欢迎来到我的技术博客——一个用代码编织思想的数字花园 🌱 3042

Nginx配置文件详解(续)

由于server_name指令支持使用通配符和正则表达式两种配置名称的方式,因此在包含有多个虚拟主机的配置文件中,可能会出现一个名称被多个虚拟主机的server_name匹配成功。在server全局块中,最常见的两个配置项是本虚拟主机的监听配置和本虚拟主机的名称或IP配置。在前面提到过,每一个http块都可以包含多个server块,而每个server块就相当于一台虚拟主机,它内部可有多台主机联合提供服务,一起对外提供在逻辑上关系密切的一组服务(或网站)。server块和“虚拟主机”的概念有密切联系。

m0_67409608的博客 1137

nginx.conf之listen与server_name的意义

nginx所在服务器上会有配置host文件,里面会写上www.test151.com指向的是局域网中的那台机器,这个时候nginx就会将请求转发到host中所配置的服务器的相应端口中;这是因为listen配上后server_name就失效了(优先匹配listen中的ip地址),当用域名访问www.test152.com的时候,客户端先将域名解析成ip地址,将请求发给nginx的时候,优先进行ip地址的匹配,当客户端通过ip地址访问的时候,直接匹配了ip地址。但是通过域名则可以匹配到指定的后端服务器。

zyqash的博客 2266

【实际操作解决自己对nginx的listen和server_name以及dns的疑惑】

1. 配置说明 /usr/local/nginx/conf/nginx.conf #user nobody; worker_processes 1; error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { in

努力学习 4606

nginx(二十五)如何找server块

一 HTTP中的Host请求头 二 nginx中与host相关的指令和变量 没有Host头nginx是如何处理的 ① 案例引入 备注:关于'虚拟主机',一般就是'相同的ip:不同port'或者'不同域名对应同一ip'两种形式 ② 命令行curl测试 现象:请求时在'请求头指定'Host: server2.wzj.com ; 此时的结果会很'出乎意料',该请求就会由'第二块'server处理. '简化'解读: 'Host'的请求头[如果是"域名的形式"]在'服务端'不做域....

wzj_110的博客 2989

04-Nginx核心配置文件详解:全局块、http块、server块、location匹配规则

前面几篇铺垫了架构和部署,这一篇啃硬骨头——配置文件。Nginx 的配置看起来像一堆花括号嵌套,新手一上来就懵。其实你把它想成一棵树,结构清晰得很:

爱片闲串,爱钓鱼,爱中医,爱分享 66
上一篇: cloud foundry vmc 部分api
下一篇: nginx静态文件处理
fjs_cloud
博客等级 码龄15年 248粉丝 192原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值