Nginx云计算难学吗好学吗?

nginx学习笔记七(nginxHTTP框架的执行流程)
之前已经介绍过nginx的事件框架。那么,对于client发出的一个http的请求,nginx的http框架是如何一步步解析这个http请求?http框架又是如何和之前介绍过得epoll事件模块结合起来的,下面来简要介绍下。
之前已经介绍过nginx的事件框架。那么,对于client发出的一个http的请求,nginx的http框架是如何一步步解析这个http请求?http框架又是如何和之前介绍过得epoll事件模块结合起来的,下面来简要介绍下。
注:我手头上的nginx工程是nginx-1.9.14的,与《深入理解nginx》的版本不一致,在http框架这块的代码上也有着较大的区别。
一.ngx_http_init_connection
在http框架初始化的时候(参见《深入理解nginx》第10章),会将每个ngx_listening_t结构体的handler方法设为ngx_http_init_connection,这是框架初始化的时候完成的工作。在整个正常工作起来之后,client每发出一个新的http连接请求,nginx的事件模块会对这个请求进行处理,最后在ngx_event_accept函数里面会调用accept系统调用来接收这个请求。而在ngx_event_accept函数的最后会调用ls-&handler即ngx_http_init_connection函数。这样一来,新的http连接就会来到http框架中的函数来进行后续的解析和处理。
ngx_http_init_connection(ngx_connection_t *c)
//当建立连接后开辟ngx_http_connection_t结构,这里面存储该服务器端ip:port所在server{}上下文配置信息,和server_name信息等,然后让
//ngx_connection_t-&data指向该结构,这样就可以通过ngx_connection_t-&data获取到服务器端的serv loc 等配置信息以及该server{}中的server_name信息
ngx_event_t
struct sockaddr_in
ngx_http_port_t
ngx_http_in_addr_t
ngx_http_log_ctx_t
ngx_http_connection_t
#if (NGX_HAVE_INET6)
struct sockaddr_in6
ngx_http_in6_addr_t
//注意ngx_connection_t和ngx_http_connection_t的区别,前者是建立连接accept前使用的结构,后者是连接成功后使用的结构
hc = ngx_pcalloc(c-&pool, sizeof(ngx_http_connection_t));
if (hc == NULL) {
ngx_http_close_connection(c);
//在服务器端accept客户端连接成功(ngx_event_accept)后,会通过ngx_get_connection从连接池获取一个ngx_connection_t结构,也就是每个客户端连接对于一个ngx_connection_t结构,
//并且为其分配一个ngx_http_connection_t结构,ngx_connection_t-&data = ngx_http_connection_t,见ngx_http_init_connection
/* find the server configuration for the address:port */
port = c-&listening-&
if (port-&naddrs & 1) {
* there are several addresses on this port and one of them
* is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
* is required to determine a server address
//说明listen ip:port存在几条没有bind选项,并且存在通配符配置,如listen *:port,那么就需要通过ngx_connection_local_sockaddr来确定
//究竟客户端是和那个本地ip地址建立的连接
if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { //
ngx_http_close_connection(c);
switch (c-&local_sockaddr-&sa_family) {
#if (NGX_HAVE_INET6)
case AF_INET6:
sin6 = (struct sockaddr_in6 *) c-&local_
addr6 = port-&
/* the last address is "*" */
for (i = 0; i & port-&naddrs - 1; i++) {
if (ngx_memcmp(&addr6[i].addr6, &sin6-&sin6_addr, 16) == 0) {
hc-&addr_conf = &addr6[i].
default: /* AF_INET */
sin = (struct sockaddr_in *) c-&local_
addr = port-&
/* the last address is "*" */
//根据上面的ngx_connection_local_sockaddr函数获取到客户端连接到本地,本地IP地址获取到后,遍历ngx_http_port_t找到对应
//的IP地址和端口,然后赋值给ngx_http_connection_t-&addr_conf,这里面存储有server_name配置信息以及该ip:port对应的上下文信息
for (i = 0; i & port-&naddrs - 1; i++) {
if (addr[i].addr == sin-&sin_addr.s_addr) {
这里也体现了在ngx_http_init_connection中获取http{}上下文ctx,如果客户端请求中带有host参数,则会继续在ngx_http_set_virtual_server
中重新获取对应的server{}和location{},如果客户端请求不带host头部行,则使用默认的server{},见 ngx_http_init_connection
hc-&addr_conf = &addr[i].
switch (c-&local_sockaddr-&sa_family) {
#if (NGX_HAVE_INET6)
case AF_INET6:
addr6 = port-&
hc-&addr_conf = &addr6[0].
default: /* AF_INET */
addr = port-&
hc-&addr_conf = &addr[0].
/* the default server configuration for the address:port */
//listen add:port对于的 server{}配置块的上下文ctx
hc-&conf_ctx = hc-&addr_conf-&default_server-&
ctx = ngx_palloc(c-&pool, sizeof(ngx_http_log_ctx_t));
if (ctx == NULL) {
ngx_http_close_connection(c);
ctx-&connection =
ctx-&request = NULL;
ctx-&current_request = NULL;
c-&log-&connection = c-&
c-&log-&handler = ngx_http_log_
c-&log-&data =
c-&log-&action = "waiting for request";
c-&log_error = NGX_ERROR_INFO;
rev-&handler = ngx_http_wait_request_
c-&write-&handler = ngx_http_empty_
#if (NGX_HTTP_SPDY)
if (hc-&addr_conf-&spdy) {
rev-&handler = ngx_http_spdy_
#if (NGX_HTTP_SSL)
ngx_http_ssl_srv_conf_t
sscf = ngx_http_get_module_srv_conf(hc-&conf_ctx, ngx_http_ssl_module);
if (sscf-&enable || hc-&addr_conf-&ssl) {
c-&log-&action = "SSL handshaking";
if (hc-&addr_conf-&ssl && sscf-&ssl.ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, c-&log, 0,
"no \"ssl_certificate\" is defined "
"in server listening on SSL port");
ngx_http_close_connection(c);
hc-&ssl = 1;
rev-&handler = ngx_http_ssl_
if (hc-&addr_conf-&proxy_protocol) {
hc-&proxy_protocol = 1;
c-&log-&action = "reading PROXY protocol";
如果新连接的读事件ngx_event_t结构体中的标志位ready为1,实际上表示这个连接对应的套接字缓存上已经有用户发来的数据,
这时就可调用上面说过的
ngx_http_wait_request_handler方法处理请求。
*/ //这里只可能是当listen的时候添加了defered参数并且内核支持,在ngx_event_accept的时候才会置1,才可能执行下面的if里面的内容,否则不会只需if里面的内容 if (rev-&ready) { /* the deferred accept(), iocp */ if (ngx_use_accept_mutex) { //如果是配置了accept_mutex,则把该rev-&handler延后处理, //实际上执行的地方为ngx_process_events_and_timers中的ngx_event_process_posted ngx_post_event(rev, &ngx_posted_events); } rev-&handler(rev); //ngx_http_wait_request_ }/*在有些情况下,当TCP连接建立成功时同时也出现了可读事件(例如,在套接字listen配置时设置了deferred选项时,内核仅在套接字上确实收到请求时才会通知epoll调度事件的回调方法),这时ngx_http_init_request方法是在图11-1的第2步中执行的。当然,在大部分情况下,ngx_http_init_request方法和ngx_http_init_connection方法都是由两个事件(TCP连接建立成功事件和连接上的可读事件)触发调用的*//*调用ngx_add_timer方法把读事件添加到定时器中,设置的超时时间则是nginx.conf中client_header_timeout配置项指定的参数。也就是说,如果经过client_header_timeout时间后这个连接上还没有用户数据到达,则会由定时器触发调用读事件的ngx_http_init_request处理方法。 */ ngx_add_timer(rev, c-&listening-&post_accept_timeout, NGX_FUNC_LINE); //把接收事件添加到定时器中,当post_accept_timeout秒还没有客户端数据到来,就关闭连接 ngx_reusable_connection(c, 1); if (ngx_handle_read_event(rev, 0, NGX_FUNC_LINE) != NGX_OK) { //当下次有数据从客户端发送过来的时候,会在ngx_epoll_process_events把对应的ready置1。 ngx_http_close_connection(c); }}
这个函数最核心的地方是设置c-&read-&handler和c-&write-&handler。因为此时TCP连接已经建立了,后续当epoll_wait返回事件的时候,需要完成的就不是TCP连接操作而是数据接收处理操作。所以这里把handler设置成了ngx_http_wait_request_handler
二.ngx_http_wait_request_handler
//客户端建立连接后,只有第一次读取客户端数据到数据的时候,执行的handler指向该函数,因此当客户端连接建立成功后,只有第一次读取
//客户端数据才会走该函数,如果在保活期内又收到客户端请求,则不会再走该函数,而是执行ngx_http_process_request_line,因为该函数
//把handler指向了ngx_http_process_request_line
static void
ngx_http_wait_request_handler(ngx_event_t *rev)
ngx_connection_t
ngx_http_connection_t
ngx_http_core_srv_conf_t
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c-&log, 0, "http wait request handler");
if (rev-&timedout) { //如果tcp连接建立后,等了client_header_timeout秒一直没有收到客户端的数据包过来,则关闭连接
ngx_log_error(NGX_LOG_INFO, c-&log, NGX_ETIMEDOUT, "client timed out");
ngx_http_close_connection(c);
if (c-&close) {
ngx_http_close_connection(c);
cscf = ngx_http_get_module_srv_conf(hc-&conf_ctx, ngx_http_core_module);
size = cscf-&client_header_buffer_ //默认1024
if (b == NULL) {
b = ngx_create_temp_buf(c-&pool, size);
if (b == NULL) {
ngx_http_close_connection(c);
c-&buffer =
} else if (b-&start == NULL) {
b-&start = ngx_palloc(c-&pool, size);
if (b-&start == NULL) {
ngx_http_close_connection(c);
b-&pos = b-&
b-&last = b-&
b-&end = b-&last +
//这里如果一次没有把所有客户端的数据读取完,则在ngx_http_process_request_line中会继续读取
//与ngx_http_read_request_header配合读
n = c-&recv(c, b-&last, size);
//读取客户端来的数据
执行ngx_unix_recv
if (n == NGX_AGAIN) {
//nginx里面采用的都是非阻塞的recv,因此当执行recv时候可能会出现还没传送完的情形,这时候recv实际上就会返回EAGAIN错误
if (!rev-&timer_set) {
ngx_add_timer(rev, c-&listening-&post_accept_timeout, NGX_FUNC_LINE);
ngx_reusable_connection(c, 1);
if (ngx_handle_read_event(rev, 0, NGX_FUNC_LINE) != NGX_OK) {
ngx_http_close_connection(c);
* We are trying to not hold c-&buffer's memory for an idle connection.
if (ngx_pfree(c-&pool, b-&start) == NGX_OK) {
b-&start = NULL;
if (n == NGX_ERROR) {
ngx_http_close_connection(c);
if (n == 0) {
ngx_log_error(NGX_LOG_INFO, c-&log, 0,
"client closed connection");
ngx_http_close_connection(c);
b-&last +=
if (hc-&proxy_protocol) {
hc-&proxy_protocol = 0;
p = ngx_proxy_protocol_read(c, b-&pos, b-&last);
if (p == NULL) {
ngx_http_close_connection(c);
if (b-&pos == b-&last) {
c-&log-&action = "waiting for request";
b-&pos = b-&
b-&last = b-&
ngx_post_event(rev, &ngx_posted_events);
c-&log-&action = "reading client request line";
ngx_reusable_connection(c, 0);
//从新让c-&data指向新开辟的ngx_http_request_t
c-&data = ngx_http_create_request(c);
if (c-&data == NULL) {
ngx_http_close_connection(c);
rev-&handler = ngx_http_process_request_
ngx_http_process_request_line(rev);
当进入这个函数的时候,一定是客户端开始往client发实际的数据了(像HTTP头,请求行等等)。那么在这个函数里面会先调用recv来接收下。由于nginx里面的recv都是非阻塞的,因此当前的recv可能会没接收到数据(比如出现client数据还没发送完这样的情况,此时recv会返回EAGAIN,这个并不是出错,而是让程序过一会再来recv看看。在非阻塞程序里面比较常见。)当出现EAGAIN的时候,需要再次把该事件注册到epoll里面去。这是因为nginx里面的epoll采用的是ET触发模式,epoll_wait模式将无法再次获取该事件,所以需要重新进行注册。然后函数会直接return,将控制权交换给HTTP框架。
如果recv返回的结果是n&0。说明此时接收到client传来的数据了,但是只recv一次可能没法读取到所有的数据,而且TCP发送端的缓存区也很可能存不下整个HTTP请求行。所以需要采取额外的措施来继续接收数据,并且判断是否接收到了完成的HTTP请求行。nginx是专门实现了一个函数ngx_http_process_request_line来完成这个事,本函数后来把handler指向了ngx_http_process_request_line。
三.ngx_http_process_request_line
static void
ngx_http_process_request_line(ngx_event_t *rev) //gx_http_process_request_line方法来接收HTTP请求行
ngx_connection_t
ngx_http_request_t
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev-&log, 0,
"http process request line");
检查这个读事件是否已经超时,超时时间仍然是nginx.conf配置文件中指定的client_header_timeout。如果ngx_event_t事件的timeout标志为1,
则认为接收HTTP请求已经超时,调用ngx_http_close_request方法关闭请求,同时由ngx_http_process_request_line方法中返回。
if (rev-&timedout) {
ngx_log_error(NGX_LOG_INFO, c-&log, NGX_ETIMEDOUT, "client timed out");
c-&timedout = 1;
ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
rc = NGX_AGAIN;
//读取一行数据,分析出请求行中包含的method、uri、http_version信息。然后再一行一行处理请求头,并根据请求method与请求头的信息来决定
//是否有请求体以及请求体的长度,然后再去读取请求体
for ( ;; ) {
if (rc == NGX_AGAIN) {
n = ngx_http_read_request_header(r);
if (n == NGX_AGAIN || n == NGX_ERROR) {
//如果内核中的数据已经读完,但这时候头部字段还没有解析完毕,则把控制器交还给HTTP,当数据到来的时候触发
//ngx_http_process_request_line,因为该函数外面rev-&handler = ngx_http_process_request_
rc = ngx_http_parse_request_line(r, r-&header_in);
if (rc == NGX_OK) { //请求行解析成功
/* the request line has been parsed successfully */
//请求行内容及长度
//GET /sample. HTTP/1.1整行
r-&request_line.len = r-&request_end - r-&request_
r-&request_line.data = r-&request_
r-&request_length = r-&header_in-&pos - r-&request_
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c-&log, 0,
"http request line: \"%V\"", &r-&request_line);
//请求方法 GET
//GET /sample.jsp HTTP/1.1
r-&method_name.len = r-&method_end - r-&request_start + 1;
r-&method_name.data = r-&request_line.
//GET /sample.jsp HTTP/1.1
中的HTTP/1.1
if (r-&http_protocol.data) {
r-&http_protocol.len = r-&request_end - r-&http_protocol.
if (ngx_http_process_request_uri(r) != NGX_OK) {
if (r-&host_start && r-&host_end) {
host.len = r-&host_end - r-&host_
host.data = r-&host_
rc = ngx_http_validate_host(&host, r-&pool, 0);
if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_INFO, c-&log, 0,
"client sent invalid host in request line");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
if (rc == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
r-&headers_in.server =
if (r-&http_version & NGX_HTTP_VERSION_10) { //1.0以下版本没有请求头部字段,
用户请求的HTTP版本小于1.0(如HTTP 0.9版本),其处理过程将与HTTP l.0和HTTP l.1的完全不同,它不会有接收HTTP
头部这一步骤。这时将会调用ngx_http_find_virtual_server方法寻找到相应的虚拟主机?
if (r-&headers_in.server.len == 0
&& ngx_http_set_virtual_server(r, &r-&headers_in.server) //http0.9应该是从请求行获取虚拟主机?
== NGX_ERROR)
ngx_http_process_request(r);
//初始化用于存放http头部行的空间,用来存放http头部行
if (ngx_list_init(&r-&headers_in.headers, r-&pool, 20,
sizeof(ngx_table_elt_t))
!= NGX_OK)
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
c-&log-&action = "reading client request headers";
rev-&handler = ngx_http_process_request_
ngx_http_process_request_headers(rev);//开始解析http头部行
if (rc != NGX_AGAIN) {//读取完毕内核该套接字上面的数据,头部行不全,则说明头部行不全关闭连接
/* there was error while a request line parsing */
ngx_log_error(NGX_LOG_INFO, c-&log, 0,
ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
//表示该行内容不够,例如recv读取的时候,没有把整行数据读取出来,返回后继续recv,然后接着上次解析的位置继续解析直到请求行解析完毕
/* NGX_AGAIN: a request line parsing is still incomplete */
如果ngx_http_parse_request_line方法返回NGX_AGAIN,则表示需要接收更多的字符流,这时需要对header_in缓冲区做判断,检查
是否还有空闲的内存,如果还有未使用的内存可以继续接收字符流,则跳转到第2步,检查缓冲区是否有未解析的字符流,否则调用
ngx_http_alloc_large_header_buffer方法分配更大的接收缓冲区。到底分配多大呢?这由nginx.conf文件中的large_client_header_buffers配置项指定。
if (r-&header_in-&pos == r-&header_in-&end) {
rv = ngx_http_alloc_large_header_buffer(r, 1);
if (rv == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
if (rv == NGX_DECLINED) {
r-&request_line.len = r-&header_in-&end - r-&request_
r-&request_line.data = r-&request_
ngx_log_error(NGX_LOG_INFO, c-&log, 0,
"client sent too long URI");
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
//表示头部行没有解析完成,继续读数据解析有点想学PHP,但是看云计算也挺不错的。到底该选哪个?【php吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:133,936贴子:
有点想学PHP,但是看云计算也挺不错的。到底该选哪个?收藏
上帝啊!我迷茫了。救救我。请大家指点一下啦!谢谢!
两个一起学 架个 站点前端nginx反向apache php再做负载均衡 想想就棒棒哒
如果是老师教的话果断学PHP,好歹是门看得见的技能,教的云计算拿出来根本没地方用,自学的话看你的情况,有编程基础的话可以看云计算,没有基础的话建议云别研究那么早,理解不了的
登录百度帐号推荐应用开发漫谈:BAT都在用的Nginx到底是啥?_网易数码
开发漫谈:BAT都在用的Nginx到底是啥?
用微信扫码二维码
分享至好友和朋友圈
(原标题:开发漫谈:BAT都在用的Nginx到底是啥?)
第1页:Nginx是什么?如果你混迹IT圈儿,你可能听说过,或见过Nginx,IT技术人员对她都会有所耳闻,云计算工程师因为要应对负载均衡问题,需要更深入的了解Nginx,而Nginx也是百度、阿里、腾讯等企业IT架构中的常客。今天,笔者就与大家一起来探究一下,Nginx究竟是什么。Nginx是什么?根据维基百科的定义,Nginx(发音同engine&x)是一个网页服务器,它能反向代理HTTP,HTTPS,SMTP,POP和IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。其初始版本发于12年前(日),起初只是供俄罗斯大型门户网站及搜索引擎Rambler(Рамблер)使用,后再2011年俄罗斯Nginx公司获得300万美元风投,也在国内外获得了大量的追随者,国内的BAT、新浪、搜狐都有应用,国外的Facebook、TechCrunch、Groupon和WordPress等公司,也是Nginx的簇拥。技术创始人为为Igor&Sysoev此软件BSD-like协议下发行,可以在UNIX、GNU/Linux、BSD、Mac&OS&X、Solaris,以及Microsoft&Windows等操作系统中均可运行。技术创始人为为Igor&Sysoev。特性如何Nginx之所以能够受到世界各大互联网公司的青睐,当然是基于前面提过的在BSD-like协议下发行,更重要的还是Nginx拥有高性能的特点,主要体现在占用内存少,稳定性高等方面。正因为这个特点,Nginx在四年前,就被某宝内部系统广泛使用。同时Nginx在处理并发服务能力方面十分优异,整体采用模块化设计,在处理负载均衡方面有着出色表现。根据Nginx的官方测试结果显示,Nginx可以支持五万个平行链接,而在实际运作中,可以支持2万至4万个平行链接。
第2页:Nginx架构如何架构如何Nginx高性能的特点很大原因要归功于Nginx的架构与设计方式。当我们启动Nginx之后,会出现一个Master进程和多个Wocker进程,Master进程主要用来管理Wocker进程,放Wocker进程异常退出后,会自动重新启动新的Wocker进程。多个Wocker进程之间是对等的,同时也是相互独立的。Nginx架构图(图片来自网络)
另外,Nginx使用了最新的epoll和kqueue网络IO模型,这种模型在高并发的情况下,时间模型能够有更高的效率。与多线程相比,这种事件处理方式优势明显,能够不需要创建线程,每个请求占用的内存也很少,没有上下文切换,事件处理十分轻量级。结束语五年前,Nginx技术创始人做了家公司,冲击了微软IIS(互联网信息服务器Internet&Information&Server),如今,互联网在快速发展中,高并发、高负载情况愈加平常,Nginx依然焕发着自己的活力。
本文来源:中关村在线
责任编辑:"王晓易_NE0011"
用微信扫码二维码
分享至好友和朋友圈
加载更多新闻
热门产品:   
:        
:         
热门影院:
阅读下一篇
用微信扫描二维码
分享至好友和朋友圈Nginx配置与解析
sudo apt-get install nginx
二、文件结构
/etc/nginx 所有的配置文件都在此目录
/etc/nginx/sites-enabled 配置虚拟主机
/usr/share/nginx/html 根目录,里面有两个默认网页 index.html和50x.html
/usr/sbin/nginx 启动程序文件
/var/log/nginx 存放日志,分别是access.log和error.log
/etc/init.d/ 启动脚本nginx
三、启动,停止,重启
看了很多参考,方法不唯一,先介绍最简单且一定有效的方法:
$nginx -s stop
$nginx -s reload
/etc/init.d/nginx start
$ ps -ef | grep nginx
master进程好为3170,终止该进程
$ sudo kill -QUIT 3170
$ /etc/init.d/nginx restart
还有很多种方法,不过目前来看,最有效的方式是采用方法一;
四、基本配置
/etc/nginx 目录下存在 nginx.conf 文件,这是nginx的配置文件,通常,我们需要对nginx设置时,都在此文件进行。
文件结构为
一个server是一个虚拟主机,我们需要添加虚拟主机时,在http下添加server,
listen 80 default_
root /usr/share/nginx/
#存放写好的网页
index index.html index.
但新版本添加server时要在/etc/nginx/sites-enabled/ 目录下的defaut文件中,原因在于nginx.conf文件中
include /etc/nginx/conf.d
其实都是读nginx.conf文件而已。很多发行版在nginx.conf底部添加include sites-enabled/*.conf、sites-available是为了方便管理,这样你就可以把已经配置好的各种 server conf 放在 sites-enabled里,如果想启用的时候只要复制或者软连接到 sites-available 或者sites-enabled文件夹里,想关掉或者换配置的时候取消include或者软连接;
五、常见的语法
1、基本配置
listen 80 default_
root /usr/share/nginx/
index index.html index.
我们自己写的网页可以放在usr/share/nginx/html 目录下进行访问。
2、内部变量
listen 80 default_
location / {
if ( $query_string ~* ^(.*)cc=(.*)$ ){
proxy_pass http://$arg_cc;
querystring代表网址的参数
arg_name 参数值
3、设置变量
listen 80 default_
location / {
set $b "";
if ( $query_string ~* ^(.*)cc=(.*)$ ){
set $b "$arg_cc";
proxy_pass http://$b;
4、服务器池的参数
upstream back{
server 192.1.1.1:80;
server 192.1.1.2:80 max_fails=3 fail_timeout=30s wight=3;
server后可以添加参数,
max_fails最大失败次数,如果3次没连上,任务服务器损坏,下次就跳过
wight 权重,优先使用权
还有其他一些参数,视情况添加。
5、个别参数说明
(1)proxy_set_head X-Forwarded_for
location / {
proxy_pass http://
proxy_set_head X-Forwarded_for $remote_addr;
(2)nginx.conf 文件
worker_processes 1;
worker_connections 1024;
worker_connections 最大并发量,最大值为1024,受制于linux系统最多打开文件数;}

我要回帖

更多关于 搜狗云计算有必要开吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信