Nginx 教程

什么是 Nginx?
Nginx是一个高性能http和反向代理服务,并且还支持正向代理和邮件服务功能。

Nginx 虚拟主机:

#一个简单虚拟主机配置:
server {
    listen 80;
    server_name t1.com www.t1.com;
    root /data/www/t1;
    index index.html;

    location [modifier] URI {...}

    access_log /var/log/nginx/t1_access.log access;
    error_log /var/log/nginx/t1_error.log warn;

    errer_page 404 /404.html;
      location = /404.html {
    }
    error_page 500 502 503 504 /50x.html;
      location = /50x.html {
        root /data/www/t1/error_page;
    }
}

#lisen常用配置方式:
listen 127.0.0.1    #相当于127.0.0.1:80,监听指定IP的默认80端口;
listen 80    #相当于*:80,监听任何IP(本地存在)的80端口;
listen 127.0.0.1:8080    #监听指定IP的指定端口;
listen unix:/var/run/nginx.socks    #监听unix套接字;

default_server标识符:
   设置虚拟主机为 "指定IP:port" 的默认主机,如果没有此参数则在此"IP:port组内"至上往下匹配;
Nginx实现多端口绑定方法:
   1.使用多个listen字段   
   2.使用多个Server配置

#server_name常用配置方式:
server_name t1.com www.t1.com   #精准匹配,存储在第一张表最先查找;
server_name *.t1.com    #以星号开始的通配符匹配,存储在第二张表第二查找;
server_name t1.*    #以星号结尾的通配符匹配,存储在第三张表第三查找;
server_name ~ ^[0-9]*\.t1\.com$ #正则匹配'~',上述三张表都没有则按照顺序进行正则匹配;

.t1.com和*.t1.com区别:
   .t1.com等同于:t1.com和*.t1.com,并且存储在第二张表中;

#虚拟主机匹配流程:
1.判断domain:port是否为nginx中开放的ip:port,是继续下一步,否无法连接;
2.根据请求的port将流量导入到对应的监听port中;
3.在关联到此port的虚拟主机组内根据server_name匹配,没有匹配到server_name扔给default_server(没有default_server至上而下匹配);
#根据上述流程,建立虚拟主机可使用以下三种方式实现不通需求:
1.基于域名的虚拟主机:使用不同域名相同端口
2.基于端口的虚拟主机:使用不同端口相同或不同域名
3.基于IP地址的虚拟主机:很少使用;
#root, location, 和 try_files 指令:

root指令:设置请求的根目录,后续请求都在根目录中查找;

location指令:根据请求的 URI 来设置配置,可以设置多个;

    方式1:
    location [modifier] uri { … }
    =           - 表示完全精准匹配,匹配成功后停止继续搜索并立即处理请求;
    ^~          - 表示优先于正则表达式的前缀匹配,立刻停止后续的正则搜索;
    ~ 或 ~*     - 表示区分大小写 或 不区分大小写的正则匹配,可以使用!进行不匹配正则;
    no modifier - 表示匹配以 url 开头的字符串只能是普通字符串;

    #匹配优先级至上而下依次降低,具体匹配顺序如下:
    首先精确匹配 =
    其次前缀匹配 ^~
    其次是按文件中顺序的正则匹配 ~ ~*
    然后匹配不带任何修饰的前缀匹配
    最后是交给 / 通用匹配
    当有匹配成功时候,停止匹配,按当前匹配规则处理请求


    前缀匹配下,返回最长匹配的 location,与 location 所在位置顺序无关
    正则匹配是使用文件中的顺序,找到返回并停止后续搜索

    方式2:
    location @name { … } nginx内部跳转

try_files指令:尝试不同的路径,找到一个路径就返回;应该避免在 server 上下文中出现 try_files;

    try_files $uri /index.html =404;
    对于 /test.html 请求,尝试按以下顺序返回文件:
    1.$uri ( /test.html )
    2.index.html
    3.如果什么都没找到则返回 404

Nginx能做什么:
1、反向代理
2、负载均衡
3、HTTP服务器(动静分离)
4、正向代理(缓存服务)

以上是Nginx在不加载第三方模块的情况下能实现的功能。

反向代理:

server {
        listen       80;                                                         
        server_name  localhost;                                               
        client_max_body_size 1024M;

        location / {
            proxy_pass http://localhost:8080;
            proxy_set_header Host $host:$server_port;
        }
    }

负载均衡:

1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

有如下参数:

在轮询中,如果服务器down掉了,会自动剔除该服务器。
此策略适合服务器配置相当,无状态且短平快的服务使用。

    upstream test {
        server localhost:8080;
        server localhost:8081;
    }
    server {
        listen       81;                                                         
        server_name  localhost;                                               
        client_max_body_size 1024M;

        location / {
            proxy_pass http://test;      #此处"http://"不能少,test为upstream定义的名称;
            proxy_set_header Host $host:$server_port;
        }
    }

2、权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况,weight默认是1。

    upstream test {
        server localhost:8080 weight=9;
        server localhost:8081 weight=1;
    }
此策略可以与least_conn和ip_hash结合使用
此策略比较适合服务器的硬件配置差别比较大的情况。

3、最少链接:
web请求会被转发到连接数最少的服务器上。

    upstream nginxDemo {
        least_conn;
        server 127.0.0.1:8081;
        server 127.0.0.1:8082;
    }
此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。

4、ip_hash
ip_hash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。当后台服务器宕机时,会自动跳转到其它服务器。

    upstream test {
        ip_hash;
        server localhost:8080;
        server localhost:8081;
    }
ip_hash不能与backup同时使用。
当有服务器需要剔除,必须手动down掉。

5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存服务器、文件服务器、静态服务器时比较有效。缺点是当后端服务器宕机的时候,url_hash不会自动跳转的其他缓存服务器,而是返回给用户一个503错误。

    upstream backend { 
        hash $request_uri; 
        hash_method crc32; 
        server localhost:8080;
        server localhost:8081;
    } 
在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

6、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。

        fair; 
        server localhost:8080;
        server localhost:8081;
    } 

HTTP服务器
Nginx本身也是一个静态资源的服务器,首先看看Nginx做静态资源服务器

    server {
        listen       80;                                                         
        server_name  localhost;                                               
        client_max_body_size 1024M;


        location / {
               root   e:wwwroot;
               index  index.html;
           }
    }

这样如果访问http://localhost 就会默认访问到E盘wwwroot目录下面的index.html,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。

动静分离
动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路

upstream test{  
       server localhost:8080;  
       server localhost:8081;  
    }   

    server {  
        listen       80;  
        server_name  localhost;  

        location / {  
            root   e:wwwroot;  
            index  index.html;  
        }  

        # 所有静态请求都由nginx处理,存放目录为html  
        location ~ .(gif|jpg|jpeg|png|bmp|swf|css|js)$ {  
            root    e:wwwroot;  
        }  

        # 所有动态请求都转发给tomcat处理  
        location ~ .(jsp|do)$ {  
            proxy_pass  http://test;  
        }  

        error_page   500 502 503 504  /50x.html;  
        location = /50x.html {  
            root   e:wwwroot;  
        }  
    }  

这样我们就可以吧HTML以及图片和css以及js放到wwwroot目录下,而tomcat只负责处理jsp和请求,例如当我们后缀为gif的时候,Nginx默认会从wwwroot获取到当前请求的动态图文件返回,当然这里的静态文件跟Nginx是同一台服务器,我们也可以在另外一台服务器,然后通过反向代理和负载均衡配置过去就好了,只要搞清楚了最基本的流程,很多配置就很简单了,另外localtion后面其实是一个正则表达式,所以非常灵活

正向代理
但是目前Nginx有一个问题,那么就是不支持HTTPS

    resolver 114.114.114.114 8.8.8.8;
    server {

        resolver_timeout 5s;

        listen 81;

        access_log  e:wwwrootproxy.access.log;
        error_log   e:wwwrootproxy.error.log;

        location / {
            proxy_pass http://$host$request_uri;
        }
    }

resolver是配置正向代理的DNS服务器,listen 是正向代理的端口,配置好了就可以在ie上面或者其他代理插件上面使用服务器ip+端口号进行代理了。

nginx 代理缓存
客户端请求nginx,nginx查看本地是否有缓存数据,若有直接返回给客户端,若没有再去后端服务器请求

http {
    proxy_cache_path    /var/www/cache #缓存地址
                        levels=1:2 #目录分级
                        keys_zone=test_cache:10m #开启的keys空间名字:空间大小(1m可以存放8000个key)
                        max_size=10g #目录最大大小(超过时,不常用的将被删除)
                        inactive=60m #60分钟内没有被访问的缓存将清理
                        use_temp_path=pff; #是否开启存放临时文件目录,关闭默认存储在缓存地址

    server {
        ...
        location / {
            proxy_cache test_cache;    #开启缓存对应的名称,在keys_zone命名好
            proxy_cache_valid 200 304 12h;    #状态码为200 304的缓存12小时
            proxy_cache_valid any 10m;    #其他状态缓存10小时
            proxy_cache_key $host$uri$is_args$args;    #设置key值
            add_header Nginx-Cache "$upstream_cache_status";
        }
    }
}

当有个特定请求我们不需要缓存的时候,在上面配置的内容中加入以下配置

server {
    ...
    if ($request_uri ~ ^/(login|register) ) {    #当请求地址有login或register时
        set $nocache = 1;    #设置一个自定义变量为true
    }
    location / {
        proxy_no_cache $nocache $arg_nocache $arg_comment;
        proxy_no_cache $http_pragma $http_authoriztion;
    }
}

常见问题
location 匹配优先级

=        #进行普通字符精确匹配,完全匹配
 ^~       #进行普通字符匹配,当前表示前缀匹配
 ~\~*     #表示执行一个正则匹配()

#当程序使用精确匹配时,一但匹配成功,将停止其他匹配
#当正则匹配成功时,会继续接下来的匹配,寻找是否还有更精准的匹配

try_files的使用

location / {
    try_files $uri $uri/ /index.php;
}

#先查找$uri下是否有文件存在,若存在直接返回给用户
#若$url下没有文件存在,再次访问$uri/的路径是否有文件存在
#还是没有文件存在,交给index.php处理

例:
location / {
    root /test/index.html
    try_files $uri @test
}

location @test {
    proxy_pass http://127.0.0.1:9090;
}

#访问 / 时,查看 /test/index.html 文件是否存在
#若不存在,让9090端口的程序去处理这个请求

alias和root的区别

location /request_path/image/ {
    root /local_path/image/;
}

#当我们访问 http://xxx.com/request_path/image/cat.png时
#将访问 http://xxx.com/request_path/image/local_path/image/cat.png 下的文件

location /request_path/image/ {
    alias /local_path/image/;
}

如果用户真实IP
当一个请求通过多个代理服务器时,用户的IP将会被代理服务器IP覆盖

#在第一个代理服务器中设置
    set x_real_ip=$remote_addr
#最后一个代理服务器中获取
    $x_real_ip=IP1

Nginx 常见错误码

413 Request Entity Too Large    #上传文件过大,设置 client_max_body_size
502 bad gateway                 #后端服务无响应
504 Gateway Time-out            #后端服务执行超时


#当我们访问 http://xxx.com/request_path/image/cat.png时
#将访问 http://xxx.com/local_path/image/cat.png 下的文件
posted @ 2020-08-07 14:41  Beavan  阅读(143)  评论(0)    收藏  举报