博客地址:https://blog.csdn.net/Weiye__Lee/article/details/79700730

写在前面

  对nginx的折腾做个汇总记录,部分内容参考出处见文章末尾.

nginx概述

nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;nginx可以作为一个HTTP服务器进行网站的发布处理,另外nginx可以作为反向代理进行负载均衡的实现。

正向代理

正向代理是一般意义上的代理。在如今的网络环境下,我们如果由于技术需要要去访问国外的某些网站,此时你会发现位于国外的某网站我们通过浏览器是没有办法访问的,此时大家可能都会用一个操作FQ进行访问,FQ的方式主要是找到一个可以访问国外网站的代理服务器,我们将请求发送给代理服务器,代理服务器去访问国外的网站,然后将访问到的数据传递给我们
上述这样的代理模式称为正向代理,正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。

这里写图片描述
这里写图片描述

反向代理

反向代理多用于分布式部署;也就是通过部署多台服务器来解决访问并发问题。

这里写图片描述
这里写图片描述

通过上述的图解大家就可以看清楚了,多个客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时,请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色
反向代理,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。对于反向这个词,刚开始接触的时候没理解为啥叫反向,这里的抽取出来注明下:

  • 正向代理
      代理服务器实现对被代理服务端隐藏客户端信息,对客户端的请求进行转发处理.此时,客户端是明确知道被代理的服务端信息的,而被代理服务端是不知道客户端信息的

  • 反向代理
      代理服务器实现对客户端的被代理服务器信息的隐藏,对客户端的请求进行转发处理.此时,客户端是不知道被代理服务端的信息的,而被代理服务端是知道客户端信息的,注意到了吧,后半句两边整好反过来

安装

ubantu包管理器安装

使用包管理器直接安装是最快捷方便的,但是缺点也明显,想自由装对应的版本就困难了。anyway,在terminal里敲如下命令:

$ sudo apt-get install nginx

安装完成即可,在/usr/sbin/目录下是nginx命令所在目录,在/etc/nginx/目录下是nginx所有的配置文件,用于配置nginx服务器以及负载均衡等信息

  • 查看nginx进程是否启动:

    $ ps -ef | grep nginx
    
  • 启动nginx服务器,直接执行nginx会按照默认的配置文件进行服务器的启动

    $ nginx # 启动
    $ nginx -s stop  停止
    $ nginx -s quit  停止
    

ubantu源码安装

 #安装gcc g++的依赖库
$ apt-get install build-essential                                     
$ apt-get install libtool        
 # 安装pcre依赖库
$ sudo apt-get install libpcre3 libpcre3-dev
 #安装 zlib依赖库
$ sudo apt-get install zlib1g-dev
 # 安装 ssl依赖库
$ sudo apt-get install openssl
 #下载nginx最新版本:参考用nginx-1.10.3/
$ wget http://nginx.org/download/nginx-1.11.3.tar.gz
 #解压:
$ tar -zxvf nginx-1.11.3.tar.gz
#进入解压目录:
$ cd nginx-1.11.3
#配置:
$ ./configure --prefix=/usr/local/nginx 
#编辑nginx:
$ make
#安装nginx:
$ sudo make install
#启动nginx:
$ sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
注意:-c 指定配置文件的路径,不加的话,nginx会自动加载默认路径的配置文件,可以通过 -h查看帮助命令。
#查看nginx进程:
$ ps -ef|grep nginx
#检查配置文件是否正确
$ sudo /usr/local/nginx/sbin/nginx -t
-----
$ /usr/local/nginx/sbin/nginx -s reload # Nginx重新加载配置
$ /usr/local/nginx/sbin/nginx -s stop #停止

nginx配置

nginx.conf

修改部署目录下conf子目录的nginx.conf文件(如上面源码安装的/usr/local/nginx/conf/nginx.conf)内容

main                                # 全局配置

events {                            # nginx工作模式配置

}

http {                                # http设置
    ....

    server {                        # 服务器主机配置
        ....
        location {                    # 路由配置
            ....
        }

        location path {
            ....
        }

        location otherpath {
            ....
        }
    }

    server {
        ....

        location {
            ....
        }
    }

    upstream name {                    # 负载均衡配置
        ....
    }
}

如上述配置文件所示,主要由6个部分组成:

  • main:用于进行nginx全局信息的配置
  • events:用于nginx工作模式的配置
  • http:用于进行http协议信息的一些配置
  • server:用于进行服务器访问信息的配置
  • location:用于进行访问路由的配置
  • upstream:用于进行负载均衡的配置

main模块

# user nobody nobody;
worker_processes 2;
# error_log logs/error.log
# error_log logs/error.log notice
# error_log logs/error.log info
# pid logs/nginx.pid
worker_rlimit_nofile 1024;

上述配置都是放在main全局配置模块中的配置项

  • user 用来指定进程运行的用户及用户组,默认为nobody
  • work_processes 用来指定nginx开启的子进程数量,数量通常是cpu内核的2倍,官方宣称一般开1个就可以了
  • error_log 定义错误日志文件的位置及输出级别[debug/info/notice/warn/error/crit]
  • pid 用来指定进程pid的存储文件的位置
  • worker_rlimit_nofile 指定一个进程可以打开的最多文件描述符数量

event 模块

event {
    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
    multi_accept on;
    use epoll;
}
  • worker_connections 指定单个进程最大可以接收的连接数量.注意,nginx最大连接数和worker_processes、worker_connections、能打开的文件描述符数量、系统资源等因素共同决定
  • multi_accept 指定nginx在收到一个新连接通知后,尽可能多的接收更多的l连接
  • use epoll 指定线程轮询的方法,如果是linux2.6+,使用epoll。如果是BSD如mac,请使用Kqueue

http 模块

作为web服务器,http模块是nginx最核心的一个模块,配置项也是比较多的,项目中会设置到很多的实际业务场景,需要根据硬件信息进行适当的配置,常规情况下,使用默认配置即可

server模块

srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机,也就是一个虚拟服务器的配置信息

server {
    listen        80;
    server_name localhost    192.168.1.100;
    root        /nginx/www;
    index        index.php index.html index.html;
    charset        utf-8;
    access_log    logs/access.log;
    error_log    logs/error.log;
    ......
}

核心配置信息如下:

  • server:一个虚拟主机的配置,一个http中可以配置多个server
  • server_name:指定ip地址或者域名,多个配置之间用空格分隔
  • root:表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录
  • index:用户访问web网站时的全局首页
  • charset:用于设置www/路径中配置的网页的默认编码格式
  • access_log:用于指定该虚拟主机服务器中的访问记录日志存放路径
  • error_log:用于指定该虚拟主机服务器中访问错误日志的存放路径

location 模块

location模块是nginx配置中出现最多的一个配置,主要用于配置路由访问信息
在路由访问信息配置中关联到负载均衡、url重写等等各项功能,所以location模块也是一个非常重要的配置模块,而其中匹配模式则是玩转转发的秘籍
匹配语法

location [ = | ~ | ~* | ^~ ] uri { ... }location @name { ... }

没错,就这么多,实际写在loacation中大概是这样的

location = / {

}
-----
location  [指令模式] url匹配模式 {

}

指令模式指用于匹配的方式,即精确匹配,前缀匹配还是正则匹配,当然这个是可选的,如果不写,则退化成正常匹配或者全匹配。url匹配模式则需要匹配的url,可以看成是web开发中的路由

匹配模式

  1. 精确匹配

    = 指令用于精确字符匹配(模式),不能使用正则,区分大小写,为了直观的观察匹配命中的location,使用rewrite指令,用于转发。目前只要理解命中了就重定向到rewrite后面的url即可

    location = /demo {    
        rewrite ^ http://google.com;
    }
    

    上述的配置表示只有访问 http://host:port/demo 这样的url,才能跳转到google的页面。除此之外的任何地址都无法访问,那怕是访问http://host:port/demo/ 这个地址也不行。因为url匹配模式是/demo

  2. 前缀匹配

    ^~指令用于字符前缀匹配,和=精确匹配一样,也是用于字符确定的匹配,不能使用正则且区分大小写。和=不同的在于,^~指令下,访问的url无需url匹配模式一模一样,只需要其开头前缀和url匹配模式一样即可

    location ^~ /demo {    
        rewrite ^ http://google.com;
    }
    

    对于该模式(/demo),访问下列的地址都能匹配:

    只需要以/demo为前缀开头的url都能匹配。与该模式后的是否大小写无关。
    ^~不支持正则。模式/demo$中的$并不代表字符模式结束,而是一个是实实在在的$,只有访问/demo$开头的url才能匹配,http://host:port/demo 则不再匹配。前缀匹配通常用于匹配文件夹,如配置静态文件。

  3. 正则匹配

    众所周知,nginx的url功能强大,配置灵活。字符匹配中,支持正则和不支持正则完全是两个境界。前面的两种方式都不能使用正则,未免让人觉得nginx有点虚夸。

    实际上,nginx支持正则匹配。所使用的指令是~和~*,前者表示使用正则,区分大小写,后者表示使用正则,不区分大小写。与前缀匹配一样,正则匹配也是只需匹配以url模式开头的即可。

    location ~ /[0-9]emo {    
        rewrite ^ http://google.com;
    }
    

    对于上述的模式,可以匹配的url如下:

    使用~*则不区分大小写

    location ~ /[0-9]EmO {    
        rewrite ^ http://google.com;
    }
    

    下面的都能匹配

  4. 正常匹配

    正常匹配的指令为空,即没有指定匹配指令的即为正常匹配。其形式类似 /XXX/YYY.ZZZ正常匹配中的url匹配模式可以使用正则,不区分大小写。

    location /demo {    
        rewrite ^ http://google.com;
    }
    

    上述模式指的是匹配/demo的url,下面的都能匹配

    正常匹配和前缀匹配的差别在于优先级。前缀的优先级高于正常匹配

  5. 全匹配

    全匹配与正常匹配一样,没有匹配指令,匹配的url模式仅一个斜杠/

    location / {    
        rewrite ^ http://google.com;
    }
    

    全匹配也可以配合 精确匹配和正则匹配一些指令,只不过这样的设定意义不大。通过都会有一个默认的location,这个就是全匹配

  6. 命名匹配

    命名匹配指的是使用@绑定一个模式,类似变量替换的用法。

    error_page 404 = @not_found
    
    location @not_found {      
        rewrite http://google.com;
    }
    

    上述的作用是如果访问没有匹配的url会触发404指令,然后就匹配到@not_found 这个 location上。

    反向代理配置示例:
    主要修改的节点为http节点,

    http {
        omitted...
        upstream backend_6001{
                 #ip_hash;                                                                          
                 server 192.168.1.207:6001;
                 server 192.168.1.207:6002;
        }
    server {
        listen       5000;
        server_name  lwy.com;
    
}
}

匹配优先级

nginx的匹配优先级遵循一个大原则和两个小细节。
大原则是关于匹配模式的优先级:

精确匹配  >  前缀匹配  >  正则匹配  > 正常匹配  > 全匹配

小细节则是同一优先级中:

  • 细节一:正则匹配成功之后停止匹配,非正则匹配成功还会接着匹配。
  • 细节二:在所有匹配成功的url中,选取匹配度最大的url字符地址。

反向代理配置

location / {

        #设置主机头和客户端真实地址,以便服务器获取客户端真实IP

             proxy_set_header Host $host;

             proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

              #禁用缓存

             proxy_buffering off;

             #设置反向代理的地址 可设为下面介绍的upstream模块

             proxy_pass http://192.168.1.1;       

      }

proxy_redirect

proxy_redirect指定修改被代理服务器返回的响应头中的location头域

location / {
            proxy_pass http://192.168.1.207:6001;
            proxy_redirect http://192.168.1.207:([1-9][0-9]*)/   http://lwy.cn:5000/lwy$1/;                                                               
        }

上面proxy_redirect配置将被代理服务器的重定向端口全部映射为/lwy$1/路由上了。然后,可以根据浏览器重定向进来的特殊路由url进行相应的配置,即配置多个location

location ~ /conwin([1-9][0-9]*)/ {
                 remainder omitted...


        }

在指令中可以使用一些变量:

proxy_redirect http://localhost:8000/ http://$host:$server_port/;

proxy_pass

在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。

假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问。

第一种:
location proxy {
proxy_pass http://127.0.0.1/;
}
代理到URL:http://127.0.0.1/test.html

第二种(相对于第一种,最后少一个 / )
location proxy {
proxy_pass http://127.0.0.1;
}
代理到URL:http://127.0.0.1/proxy/test.html

第三种:
location proxy {
proxy_pass http://127.0.0.1/aaa/;
}
代理到URL:http://127.0.0.1/aaa/test.html

第四种(相对于第三种,最后少一个 / )
location proxy {
proxy_pass http://127.0.0.1/aaa;
}
代理到URL:http://127.0.0.1/aaatest.html

upstream模块

upstream模块主要负责负载均衡的配置,通过默认的轮询调度方式来分发请求到后端服务器

upstream backend {
    ip_hash;
    server 192.168.1.100:8000;
    server 192.168.1.100:8001 down;
    server 192.168.1.100:8002 max_fails=3;
    server 192.168.1.100:8003 fail_timeout=20s;
    server 192.168.1.100:8004 max_fails=3 fail_timeout=20s;
}
 location / {



             #反向代理的地址

             proxy_pass http://backend;     

        }

核心配置信息如下

  • ip_hash:指定请求调度算法,默认是weight权重轮询调度,可以指定
  • server host:port:分发服务器的列表配置
  • – down:表示该主机暂停服务
  • – max_fails:表示失败最大次数,超过失败最大次数暂停服务
  • – fail_timeout:表示如果请求受理失败,暂停指定的时间之后重新发起请求

其中,nginx支持的负载均衡调度算法方式如下:

  • weight轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
  • ip_hash:每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。
  • fair:智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块
  • url_hash:按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包

遇到的问题

遇到301、302这种重定向的http状态码,浏览器被重定向到其他服务器地址或端口(如内网)。

  这种问题通常出现在被代理的服务端不知道代理服务器的存在,直接返回302重定向到另外一个服务器或端口(server2),nginx如果不做处理则浏览器会直接取访问server2,这样便绕过了nginx,如果是内网地址,呵呵,就访问失败了.这时候可以使用location匹配下的proxy_redirect来拦截节点被代理服务器的重定向信息

  

本文由Weiye Lee原创,转载请注明来源,谢谢:
http://blog.csdn.net/Weiye__Lee/article/details/79472815


参考

Nginx安装及配置详解:https://www.cnblogs.com/zhouxinfei/p/7862285.html

Nginx高级应用之Location Url 配置:https://www.linuxidc.com/Linux/2017-03/141910.htm