一文读懂 nginx 基础知识

301 阅读4分钟

www.nginx.cn/nginxchscom…

#运行用户 user nobody; #启动进程,通常设置成和cpu的数量相等 worker_processes 1;

#全局错误日志及PID文件 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;

#pid logs/nginx.pid;

#工作模式及连接数上限 events { #epoll是多路复用IO(I/O Multiplexing)中的一种方式, #仅用于linux2.6以上内核,可以大大提高nginx的性能 use epoll;

#单个后台worker process进程的最大并发链接数    
worker_connections  1024;

# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4  为什么
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535

}

http { #设定mime类型,类型由mime.type文件定义 include mime.types; default_type application/octet-stream; #设定日志格式 log_format main 'remoteaddrremote_addr - remote_user [timelocal]"time_local] "request" ' 'statusstatus body_bytes_sent "http_referer" ' '"http_user_agent" "$http_x_forwarded_for"';

access_log  logs/access.log  main;

#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile     on;
#tcp_nopush     on;

#连接超时时间
#keepalive_timeout  0;
keepalive_timeout  65;
tcp_nodelay     on;

#开启gzip压缩
gzip  on;
gzip_disable "MSIE [1-6].";

#设定请求缓冲
client_header_buffer_size    128k;
large_client_header_buffers  4 128k;


#设定虚拟主机配置
server {
    #侦听80端口
    listen    80;
    #定义使用 www.nginx.cn访问
    server_name  www.nginx.cn;

    #定义服务器的默认网站根目录位置
    root html;

    #设定本虚拟主机的访问日志
    access_log  logs/nginx.access.log  main;

    #默认请求
    location / {
        
        #定义首页索引文件的名称
        index index.php index.html index.htm;   

    }

    # 定义错误提示页面
    error_page   500 502 503 504 /50x.html;
    location = /50x.html {
    }

    #静态文件,nginx自己处理
    location ~ ^/(images|javascript|js|css|flash|media|static)/ {
        
        #过期30天,静态文件不怎么更新,过期可以设大一点,
        #如果频繁更新,则可以设置得小一点。
        expires 30d;
    }

    #PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
    location ~ .php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    #禁止访问 .htxxx 文件
        location ~ /.ht {
        deny all;
    }

}

}

不写last和break - 那么流程就是依次执行这些rewrite

  1. rewrite break - url重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变
  2. rewrite last - url重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变
  3. rewrite redirect – 返回302临时重定向,地址栏显示重定向后的url,爬虫不会更新url(因为是临时)
  4. rewrite permanent – 返回301永久重定向, 地址栏显示重定向后的url,爬虫更新url

Nginx是俄罗斯人Igor Sysoev基于C语言编写的十分轻量级的HTTP服务器,它主要有以下特点:

它是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器;

Nginx使用异步事件驱动的方法来处理请求,Nginx的模块化事件驱动架构可以在高负载下提供更可预测的性能;

作为Web服务器,Nginx处理静态文件、索引文件,自动索引的效率非常高

作为反向代理服务器,Nginx可以实现反向代理加速,提高网站运行速度

作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持HTTP代理服务器对外进行服务,同时还支持简单的容错和利用算法进行负载均衡

Nginx是专门为性能优化而开发的,非常注重效率,Nginx在官方测试的结果中,能够支持五万个并行连接,而在实际的运作中,可以支持二万至四万个并行链接

在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级

nginx如何配置?

Nginx的配置文件默认存放路径是etc/nginx/nginx.conf,可以在Nginx启动时添加参数–conf-path=PATH来更改nginx.conf文件的存放路径。nginx.conf中的配置信息主要包含以下五个部分:

main(全局设置):主要是包括Nginx工作进程,日志的配置以及server,location中一些共用的配置

events(连接设置):主要包括Nginx连接信息的配置

server(主机设置):主要是包括主机名称,Ip,路径解析,http请求头设置,反向代理等配置

upstream(上游服务器设置):主要为反向代理服务器信息、负载均衡等相关配置

location(URL匹配):特定URL的匹配设置

以上每部分包含若干个条指令,他们之间的关系是:server继承main,location继承server,main部分设置的指令将影响其它所有部分的设置,server部分的设置将影响到location部分的设置。upstream既不会继承指令也不会被继承,它有自己的特殊指令,不需要在其他地方的应用。

nginx中location部分url如何匹配?

location主要是匹配url中除去server_name(主机名)后的部分,其中关于url的匹配规则有以下几种:

精确匹配:以“=”开头表示精确匹配

开头匹配:^~ 表示uri以某个常规字符串开头,不是正则匹配

区分大小写的正则匹配:~开头表示区分大小写的正则匹配

不区分大小写的正则匹配:~* 开头表示不区分大小写的正则匹配

通用匹配:匹配url的前面部分

对于上述五类匹配,它们之间的匹配顺序和优先级关系如下:

不同类型之间匹配和location的顺序无关,只和优先级有关,各种匹配规则的优先级关系是: [精确匹配] > [开头匹配] > [正则匹配] > [通用匹配];

除了通用匹配,开头匹配以外,相同类型的匹配优先级只和顺序有关,排在前面的优先匹配;

通用匹配和开头匹配的优先级与通用匹配的最长字符串有关,通用字符串越长,匹配优先级越高;

下面是我设置的几个location,并测试和验证以上匹配规则:

server {

listen 80 default_server;

server_name dev.zdp.com;

通用匹配 [匹配规则0]

location /

{

return 302 www.pangshuhai.com

}

通用匹配 [匹配规则1]

location /hello

{

return 302 www.pangshuhai.com;

}

通用匹配 [匹配规则2]

location /hello/no

{

return 302 dev.youdata.com;

}

不区分大小写的正则匹配 [匹配规则3]

location ~* /hello/y[a-e][a-z][1-9]

{

return 302 www.pangshuhai.com;

}

区分大小写的正则匹配 [匹配规则4]

location ~ /hello/y[A-E][E-Z][1-9]

{

return 302 www.pangshuhai.com;

}

区分大小写的正则匹配 [匹配规则5]

location ~ /hello/y[a-e][e-z]

{

return 302 www.pangshuhai.com;

}

开头匹配 [匹配规则6]

location ^~ /hello/yes

{

return 302 www.pangshuhai.com;

}

开头匹配 [匹配规则7]

location ^~ /hello/yesno

{

return 302 www.pangshuhai.com;

}

精确匹配 [匹配规则8]

location = /gushi

{

return 302 gushi.pangshuhai.com

}

}

location用例测试:

www.pangshuhai.com/hello” ——- 精确匹配优先,命中[匹配规则8]

www.pangshuhai.com/hello/yesno… ——- 开头匹配优先,开头匹配同时满足条件时,长优先,命中[匹配规则7]

www.pangshuhai.com/hello/yesOk… ——- 开头匹配优先,命中[匹配规则6]

www.pangshuhai.com/hello/yaz” ——- 正则匹配,命中[匹配规则5]

www.pangshuhai.com/hello/yAZ3” ——- 正则匹配,按照location顺序匹配,命中[匹配规则3]

www.pangshuhai.com/hello/no” ——- 通用匹配,按照匹配长度优先,命中[匹配规则2]

www.pangshuhai.com/hello/Ok” ——- 通用匹配,命中[匹配规则1]

www.pangshuhai.com/everyone” ——- 通用匹配,所有其它匹配不满足时,命中[匹配规则0]

nginx中rewrite命令如何重写url?

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在server{},location{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如:

dev.zdp.com/a/we/index.… => rewrite只能对/a/we/index.php部分重写

server {

rewrite 规则 定向路径 重写flag;

}

location {

rewrite 规则 定向路径 重写flag;

}

rewrite的执行顺序

执行server块的rewrite指令;执行location匹配;执行选定的location中的rewrite指令,如果location中rewrite指令没有break的flag,则会根据当前rewrite路径重新匹配location;如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件,循环最多不会超过10次;

rewrite的flag标志

last: 停止处理当前location中的ngxhttprewritemodule指令集(rewrite,return等),并开始重新搜索与更改后的URI相匹配的locationbreak : 停止处理当前location中的ngxhttprewritemodule指令集(rewrite,return等),不会重新搜索redirect : 返回302临时重定向,地址栏会显示跳转后的地址permanent : 返回301永久重定向,地址栏会显示跳转后的地址default: 默认标志,继续会处理当前location中的ngxhttprewrite_module指令集(rewrite,return等),如果没有return,会开始重新搜索与更改后的URI相匹配的location

nginx中if判断如何使用?

只是上面的简单重写很多时候满足不了需求,比如需要判断当文件不存在时、当路径包含xx时等条件,则需要用到if

Nginx中if语法为:if(condition){…},对给定的条件condition进行判断。如果为真,大括号内命令将被执行

if判断规则

当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false

直接比较变量和内容时,使用=或!=

正则表达式匹配,*不区分大小写的匹配,!~区分大小写的正则表达式不匹配,满足条件返回true

-f和!-f用来判断是否存在文件

-d和!-d用来判断是否存在目录

-e和!-e用来判断是否存在文件或目录

-x和!-x用来判断文件是否可执行

if使用举例

if条件中一般会使用到一些变量,这些变量有些是用户定义的,有些是系统本身存在的,关于变量相关内容请看下文[Nginx中如何使用变量?]

server {

if ($http_user_agent ~ MSIE) {

rewrite ^(.*)/msie/ /msie/1 break;

}

如果UA包含"MSIE",rewrite请求到/msid/目录下

if (httpcookie "id=([;]+)(?:;http_cookie ~* "id=([^;]+)(?:;|)") {

set idid 1;

}

如果cookie匹配正则,设置变量$id等于正则引用部分

if ($request_method = POST) {

return 405;

}

如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302

if ($slow) {

limit_rate 10k;

}

限速,$slow可以通过 set 指令设置

if (!-f $request_filename){

break;

proxy_pass http://127.0.0.1;

}

如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查

if ($args ~ post=140){

rewrite ^ example.com/ permanent;

}

如果query string中包含"post=140",永久重定向到example.com

location ~* .(gif|jpg|png|swf|flv)$ {

valid_referers none blocked www.jefflei.com www.leizhenfang.com;

if ($invalid_referer) {

return 404;

}

防盗链

}

}

nginx变量如何使用?

Nginx也可以使用变量,变量分为系统变量和自定义变量

变量特点

Nginx变量的创建只能发生在Nginx配置加载的时候,或者说Nginx启动的时候;

Nginx变量的赋值操作则只会发生在请求实际处理的时候;

每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,它们之间的值彼此互不干扰;

自定义变量

自定义变量通过set命令初始化和赋值,变量名前需要加$符号作为区分

设置变量$a = "helloworld";

set $a hello world;

设置变量$b = "helloworld, helloworld";

set b"b "a, $a";

nginx中一些常用的命令

nginx -t 检查配置是否可用

nginx -s reload 重启nginx

Nginx location的匹配规则

~ 波浪线表示执行一个正则匹配,区分大小写 * 表示执行一个正则匹配,不区分大小写 ^ ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录 = 进行普通字符精确匹配 @ #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files

location 匹配优先级

= 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。 普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。 ^~ 则只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。 最后匹配理带有""和"*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。

try_files的用处

location / { root /var/www/build; index index.html index.htm; try_files uriuri uri/ @rewrites; }

location @rewrites { rewrite ^(.+)$ /index.html last; }

try_files从字面上理解就是尝试文件,再结合环境理解就是“尝试读取文件”(读取静态文件)

uri这个是nginx的一个变量,存放着用户访问的地址,比如:http://www.pangshuhai.com/index.html,那么uri 这个是nginx的一个变量,存放着用户访问的地址, 比如:http://www.pangshuhai.com/index.html, 那么uri就是 /index.html

uri/代表访问的是一个目录,比如:http://www.pangshuhai.com/hello/test/,那么uri/ 代表访问的是一个目录,比如:http://www.pangshuhai.com/hello/test/ ,那么uri/就是 /hello/test/

完整的解释就是:try_files 去尝试到网站目录读取用户访问的文件,如果第一个变量存在,就直接返回; 不存在继续读取第二个变量,如果存在,直接返回;不存在直接跳转到第三个参数上。

比如用户访问这个网地址:www.pangshuhai.com/test.html try_files首先会判断他是文件,还是一个目录,结果发现他是文件,与第一个参数 $uri变量匹配。 然后去到网站目录下去查找test.html文件是否存在,如果存在直接读取返回。如果不存在直接跳转到第三个参数,而第三个参数是一个location,而这个location里面配置的就是rewrite规则。