ngnix配置

2020-11-17  本文已影响0人  努力的画好人生这幅画

致敬原文作者,原文地址:https://www.nginx.cn/115.html

一、ngnix配置参数详解

#运行用户
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  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $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;
 ## 设置本地后端服务代理,若想设置为线上代理,换访问地址即可
     upstream useHD {      
      server 127.0.0.1:9201;
    }
    #设定虚拟主机配置
    server {
        #侦听80端口
        listen    9200;
        #定义使用 127.0.0.1访问
        server_name  127.0.0.1;
 
        #定义服务器的默认网站根目录位置
        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;
        }
## 表示路径为:use文件夹下 的A、B、C,实际查找的是/Users/xxx/Documents/USE/folder下的文件
    location ~ ^/use/(A|B|C) {
         root    /Users/xxx/Documents/USE/folder; 
                expires      30d;
        }
##如果要代理到use下的A文件下的vue文件里可使用:
        location ~ ^/use/(A) {
                root    /Users/xxx/Documents/USE/folder;
                try_files $uri $uri/ /index.html $1/vue/index.html last;
                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;
        }
      ## 配置后端服务器
       location ~ {
                proxy_pass   http://useHD;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        #禁止访问 .htxxx 文件
            location ~ /.ht {
            deny all;
        }
 
    }
}

二、nginx命令行参数

不像许多其他软件系统,Nginx 仅有几个命令行参数,完全通过配置文件来配置

-c </path/to/config> 为 Nginx 指定一个配置文件,来代替缺省的。

-t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。

-v 显示 nginx 的版本。

-V 显示 nginx 的版本,编译器版本和配置参数。

三、 nginx控制信号

可以使用信号系统来控制主进程。默认,nginx 将其主进程的 pid 写入到 /usr/local/nginx/nginx.pid 文件中。通过传递参数给 ./configure 或使用 pid 指令,来改变该文件的位置。

主进程可以处理以下的信号:

| TERM, INT | 快速关闭 |
| QUIT | 从容关闭 |
| HUP | 重载配置
用新的配置开始新的工作进程
从容关闭旧的工作进程 |
| USR1 | 重新打开日志文件 |
| USR2 | 平滑升级可执行程序。 |
| WINCH | 从容关闭工作进程 |

尽管你不必自己操作工作进程,但是,它们也支持一些信号:

| TERM, INT | 快速关闭 |
| QUIT | 从容关闭 |
| USR1 | 重新打开日志文件 |

四、 nginx 启动、停止、重启命令

1、nginx启动

sudo /usr/local/nginx/nginx (nginx二进制文件绝对路径,可以根据自己安装路径实际决定)

2、nginx从容停止命令,等所有请求结束后关闭服务

ps -ef |grep nginx

kill -QUIT nginx主进程号

3、nginx 快速停止命令,立刻关闭nginx进程

ps -ef |grep nginx

kill -TERM nginx主进程号

4、如果以上命令不管用,可以强制停止

kill -9 nginx主进程号

如果嫌麻烦可以不用查看进程号,直接使用命令进行操作
其中/usr/local/nginx/nginx.pid 为nginx.conf中pid命令设置的参数,用来存放nginx主进程号的文件
kill -信号类型(HUP|TERM|QUIT) cat /usr/local/nginx/nginx.pid
例如
kill -QUIT cat /usr/local/nginx/nginx.pid

5、nginx重启命令

nginx重启可以分成几种类型

(1)简单型,先关闭进程,修改你的配置后,重启进程。
kill -QUIT cat /usr/local/nginx/nginx.pid
sudo /usr/local/nginx/nginx

两个虚拟主机(纯静态-html 支持) - Two Virtual Hosts, Serving Static Files

http {
    server {
        listen          80;
        server_name     www.domain1.com;
        access_log      logs/domain1.access.log main;
        location / {
            index index.html;
            root  /var/www/domain1.com/htdocs;
        }
    }
    server {
        listen          80;
        server_name     www.domain2.com;
        access_log      logs/domain2.access.log main;
        location / {
            index index.html;
            root  /var/www/domain2.com/htdocs;
        }
    }
}
http {
    server {
        listen          80;
        server_name     www.domain1.com;
        access_log      logs/domain1.access.log main;
        location / {
            index index.html;
            root  /var/www/domain1.com/htdocs;
        }
    }
    server {
        listen          80;
        server_name     www.domain2.com;
        access_log      logs/domain2.access.log main;
        location / {
            index index.html;
            root  /var/www/domain2.com/htdocs;
        }
    }
}

虚拟主机标准配置(简化) - A Default Catchall Virtual Host

http {
    server {
        listen          80 default;
        server_name     _ *;
        access_log      logs/default.access.log main;
        location / {
            index index.html;
            root  /var/www/default/htdocs;
        }
    }
}
http {
    server {
        listen          80 default;
        server_name     _ *;
        access_log      logs/default.access.log main;
        location / {
            index index.html;
            root  /var/www/default/htdocs;
        }
    }
}

在父文件夹中建立子文件夹以指向子域名 - Wildcard Subdomains in a Parent Folder
这是一个添加子域名(或是当DNS已指向服务器时添加一个新域名)的简单方法。需要注意的是,我已经将FCGI配置进该文件了。如果你只想使服务器为静态文件服务,可以直接将FCGI配置信息注释掉,然后将默认主页文件变成index.html。

这个简单的方法比起为每一个域名建立一个 vhost.conf 配置文件来讲,只需要在现有的配置文件中增加如下内容:

server {
        # Replace this port with the right one for your requirements
        # 根据你的需求改变此端口
        listen       80;  #could also be 1.2.3.4:80 也可以是1.2.3.4:80的形式
        # Multiple hostnames seperated by spaces.  Replace these as well.
        # 多个主机名可以用空格隔开,当然这个信息也是需要按照你的需求而改变的。
        server_name  star.yourdomain.com *.yourdomain.com www.*.yourdomain.com;
        #Alternately: _ *
        #或者可以使用:_ * (具体内容参见本维基其他页面)
        root /PATH/TO/WEBROOT/$host;
        error_page  404              http://yourdomain.com/errors/404.html;
        access_log  logs/star.yourdomain.com.access.log;
        location / {
            root   /PATH/TO/WEBROOT/$host/;
            index  index.php;
        }
        # serve static files directly
        # 直接支持静态文件 (爱月说:???从配置上看来不是直接支持啊~有问题有问题~)
        location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html)$ {
            access_log        off;
            expires           30d;
        }
        location ~ .php$ {
          # By all means use a different server for the fcgi processes if you need to
          # 如果需要,你可以为不同的FCGI进程设置不同的服务信息
          fastcgi_pass   127.0.0.1:YOURFCGIPORTHERE;
          fastcgi_index  index.php;
          fastcgi_param  SCRIPT_FILENAME  /PATH/TO/WEBROOT/$host/$fastcgi_script_name;
          fastcgi_param  QUERY_STRING     $query_string;
          fastcgi_param  REQUEST_METHOD   $request_method;
          fastcgi_param  CONTENT_TYPE     $content_type;
          fastcgi_param  CONTENT_LENGTH   $content_length;
          fastcgi_intercept_errors on;
        }
        location ~ /.ht {
            deny  all;
        }
     }

(2)mac本可能需要如下命令
brew services restart nginx

五、 nginx location

1、location格式

location有两种格式:

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

2、location匹配参数解释

(1)location匹配命令

(2)location 匹配的优先级(与location在配置文件中的顺序无关)

(3)location 优先级

location  =  /  {
  # 只匹配"/".
  [  configuration  A  ]
}
location  /  {
  # 匹配任何请求,因为所有请求都是以"/"开始
  # 但是更长字符匹配或者正则表达式匹配会优先匹配
  [  configuration  B  ]
}
location  ^~  /images/  {
  # 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
  [  configuration  C  ]
}
location  ~*  .(gif|jpg|jpeg)$  {
  # 匹配以 gif, jpg, or jpeg结尾的请求.
  # 但是所有 /images/ 目录的请求将由 [Configuration C]处理.  
  [  configuration  D  ]
}

请求URI例子:

@location 例子
error_page 404 = @fetch;

location @fetch(
proxy_pass http://fetch;
)

(4)一文彻底读懂nginx中的location指令
location指令是nginx中最关键的指令之一,location指令的功能是用来匹配不同的url请求,进而对请求做不同的处理和响应,这其中较难理解的是多个location的匹配顺序,本文会作为重点来解释和说明。

开始之前先明确一些约定,我们输入的网址叫做请求URI,nginx用请求URI与location中配置的URI做匹配。

3、location匹配顺序

nginx有两层指令来匹配请求URI。第一个层次是server指令,它通过域名、ip和端口来做第一层级匹配,当找到匹配的server后就进入此server的location匹配。location的匹配并不完全按照它们在配置文件中出现的顺序来匹配,请求URI会按如下规则跟server里配置的location匹配。

(1)寻找有没有“=”等号参数完全匹配的location,如果有完全匹配的等号location则停止匹配,执行该location中的指令,不去匹配其它类型的location。
(2)匹配所有非正则表达式URI的location(包括空,=,^~三种参数)。找到请求URI和location URI按前缀匹配最长的location,如果这个最长的location的参数是^~,则停止匹配,执行该location中的指令,否则暂存该location。
(3)匹配正则表达式URI的location(包括*两种参数),按location在配置文件中出现的顺序匹配,如果找到第一个匹配的locaiton则停止匹配,执行该location。
(4)匹配完所有正则表达式都没有匹配的location,则执行第二步中暂存的最长前缀匹配location。

简单来说按这个规则:
= > ~^> ~ = ~* >最长前缀匹配 > /

4、 匹配问号后的参数

请求URI中问号后面的参数是不能在location中匹配到的,这些参数存储在$query_string变量中,可以用if来判断。

例如,对于参数中带有单引号'进行匹配然后重定向到错误页面。
/plus/list.php?tid=19&mid=1124

5、location URI结尾带不带/

location  `**/images/**` {
  proxy_pass http://www.redis.com.cn
}

对于这种情况,nginx会做特殊处理,不管images命名的文件或目录存在不在,如果你访问http://www.nginx.cn/images会被重定向到http://www.nginx.cn/images/

所以如果你想这两种请求对应不同的处理,就要明确增加不带/结尾的location配置。

location  `**/images**` {
  proxy_pass http://www.rabbitmq.cn
}
location  `**/images/**` {
  proxy_pass http://www.redis.com.cn
}

命名location

带有"@"的location是用来定义一个命名的location,这种location不参与请求匹配,一般用在内部定向。例如用在error_page, try_files命令中。它的功能类似于编程中的goto。

location  `**/images**` {
  try_files $uri $uri/ @name;
}
location  `**@name**` {
  ...
}

例子

location  = / {
  # 只匹配请求 "/"
  [ configuration A ] 
}
location  / {
  # 匹配任何请求,因为所有请求都是以"/"开始
  # 但是更长字符匹配或者正则表达式匹配会优先匹配
  [ configuration B ] 
}
location /documents/ {
  # 匹配所有 /documents/ 开头的请求,在没有正则表达
  # 式匹配时选择该locaiton
  [ configuration C ]
}
location ^~ /images/ {
  # 匹配任何以 /images/ 开始的请求,并停止匹配其它location
  [ configuration D ] 
}E
location ~* .(gif|jpg|jpeg)$ {
  # 匹配以 gif, jpg, or jpeg结尾的请求. 
  # 但是所有 /images/ 目录的请求将由 [Configuration D]处理.   
  [ configuration E ] 
}

请求URI例子:

  1. / -> 匹配A
  2. /index.html -> 匹配B
  3. /documents/a.html -> 匹配C
  4. /images/1.gif -> 匹配D
  5. /documents/1.jpg -> 匹配E

六、 nginx upstream 配置和作用

配置例子

upstream{
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;
    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}
server {
    location / {
        proxy_pass http://**backend**;
    }
}

指令

定义一组服务器。 这些服务器可以监听不同的端口。 而且,监听在TCP和UNIX域套接字的服务器可以混用。
例:

upstream {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
}

默认情况下,nginx按加权轮转的方式将请求分发到各服务器。 在上面的例子中,每7个请求会通过以下方式分发: 5个请求分到backend1.example.com, 一个请求分到第二个服务器,一个请求分到第三个服务器。 与服务器通信的时候,如果出现错误,请求会被传给下一个服务器,直到所有可用的服务器都被尝试过。 如果所有服务器都返回失败,客户端将会得到最后通信的那个服务器的(失败)响应结果。

定义服务器的地址address和其他参数parameters。 地址可以是域名或者IP地址,端口是可选的,或者是指定“unix:”前缀的UNIX域套接字的路径。如果没有指定端口,就使用80端口。 如果一个域名解析到多个IP,本质上是定义了多个server。

你可以定义下面的参数:weight=number设定服务器的权重,默认是1。max_fails=number设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。 失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。 你可以通过指令proxy_next_upstream、 fastcgi_next_upstream和memcached_next_upstream来配置什么是失败的尝试。 默认配置时,http_404状态不被认为是失败的尝试。fail_timeout=time设定

默认情况下,该超时时间是10秒。backup标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。down标记服务器永久不可用,可以跟ip_hash指令一起使用。

例:

upstream {
    server backend1.example.com     weight=5;
    server 127.0.0.1:8080           max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;

    server backup1.example.com:8080 backup;
}

指定服务器组的负载均衡方法,请求基于客户端的IP地址在服务器间进行分发。 IPv4地址的前三个字节或者IPv6的整个地址,会被用来作为一个散列key。 这种方法可以确保从同一个客户端过来的请求,会被传给同一台服务器。除了当服务器被认为不可用的时候,这些客户端的请求会被传给其他服务器,而且很有可能也是同一台服务器。

从1.3.2和1.2.2版本开始支持IPv6地址。

如果其中一个服务器想暂时移除,应该加上down参数。这样可以保留当前客户端IP地址散列分布。

例子:

upstream backend {
    ip_hash;

    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com **down**;
    server backend4.example.com;
}

从1.3.1和1.2.2版本开始,ip_hash的负载均衡方法才支持设置服务器权重值。
这个指令出现在版本 1.1.4.
激活对上游服务器的连接进行缓存。
connections参数设置每个worker进程与后端服务器保持连接的最大数量。这些保持的连接会被放入缓存。 如果连接数大于这个值时,最久未使用的连接会被关闭。

需要注意的是,keepalive指令不会限制Nginx进程与上游服务器的连接总数。 新的连接总会按需被创建。 connections参数应该稍微设低一点,以便上游服务器也能处理额外新进来的连接。
配置memcached上游服务器连接keepalive的例子:

upstream {
    server 127.0.0.1:11211;
    server 10.0.0.2:11211;
    keepalive 32;
}
server {
    ...
    location /memcached/ {
        set $memcached_key $uri;
        memcached_pass memcached_backend;
    }
}

对于HTTP代理,proxy_http_version指令应该设置为“1.1”,同时“Connection”头的值也应被清空。

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

另外一种选择是,HTTP/1.0协议的持久连接也可以通过发送“Connection: Keep-Alive”头来实现。不过不建议这样用。

对于FastCGI的服务器,需要设置 fastcgi_keep_conn 指令来让连接keepalive工作:

upstream fastcgi_backend {
    server 127.0.0.1:9000;
    keepalive 8;
}
server {
    ...
    location /fastcgi/ {
        fastcgi_pass fastcgi_backend;
        fastcgi_keep_conn on;
        ...
    }
}

当使用的负载均衡方法不是默认的轮转法时,必须在keepalive 指令之前配置。

针对SCGI和uwsgi协议,还没有实现其keepalive连接的打算。

这个指令出现在版本 1.3.1 和 1.2.2.

指定服务器组的负载均衡方法,根据其权重值,将请求发送到活跃连接数最少的那台服务器。 如果这样的服务器有多台,那就采取有权重的轮转法进行尝试。

嵌入的变量

ngx_http_upstream_module模块支持以下嵌入变量:

$upstream_addr保存服务器的IP地址和端口或者是UNIX域套接字的路径。 在请求处理过程中,如果有多台服务器被尝试了,它们的地址会被拼接起来,以逗号隔开,比如: “192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock”。 如果在服务器之间通过“X-Accel-Redirect”头或者error_page有内部跳转,那么这些服务器组之间会以冒号隔开,比如:“192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock : 192.168.10.1:80, 192.168.10.2:80”。$upstream_response_time以毫秒的精度保留服务器的响应时间,(输出)单位是秒。 出现多个响应时,也是以逗号和冒号隔开。$upstream_status保存服务器的响应代码。 出现多个响应时,也是以逗号和冒号隔开。$upstream_http_...保存服务器的响应头的值。比如“Server”响应头的值可以通过$upstream_http_server变量来获取。 需要注意的是只有最后一个响应的头会被保留下来。

七、nginx rewrite 指令

nginx通过ngx_http_rewrite_module模块支持url重写、支持if条件判断,但不支持else。

该模块需要PCRE支持,应在编译nginx时指定PCRE源码目录

nginx rewrite指令执行顺序:

1.执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
2.执行location匹配
3.执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件

如果循环超过10次,则返回500 Internal Server Error错误

break指令

语法:break;
默认值:无
作用域:server,location,if

停止执行当前虚拟主机的后续rewrite指令集
break指令实例:

if  ($slow)  {

 limit_rate  10k;

 break;

}

if指令

语法:if(condition){...}
默认值:无
作用域:server,location
对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行。
if条件(conditon)可以是如下任何内容:

if指令实例

if  ($http_user_agent  ~  MSIE)  {
 rewrite  ^(.*)$  /msie/$1  break;
}
if  ($http_cookie  ~*  "id=([^;]+)(?:;|$)")  {
 set  $id  $1;
}
if  ($request_method  =  POST)  {
 return  405;

}
if  ($slow)  {
 limit_rate  10k;
}
if  ($invalid_referer)  {
 return  403;
}

return指令

语法:return code;
return code URL;
return URL;
默认值:无
作用域:server,location,if

停止处理并返回指定状态码(code)给客户端。
非标准状态码444表示关闭连接且不给客户端发响应头。
从0.8.42版本起,return 支持响应URL重定向(对于301,302,303,307),或者文本响应(对于其他状态码).
对于文本或者URL重定向可以包含变量

rewrite指令

语法:rewrite regex replacement [flag];
默认值:无
作用域:server,location,if
如果一个URI匹配指定的正则表达式regex,URI就按照replacement重写。
rewrite按配置文件中出现的顺序执行。flags标志可以停止继续处理。
如果replacement以"http://"或"https://"开始,将不再继续处理,这个重定向将返回给客户端。
flag可以是如下参数
last 停止处理后续rewrite指令集,然后对当前重写的新URI在rewrite指令集上重新查找。
break 停止处理后续rewrite指令集,并不在重新查找,但是当前location内剩余非rewrite语句和location外的的非rewrite语句可以执行。
redirect 如果replacement不是以http:// 或https://开始,返回302临时重定向
permant 返回301永久重定向
最终完整的重定向URL包括请求scheme(http://,https://等),请求的server_name_in_redirect和 port_in_redirec三部分 ,说白了也就是http协议 域名 端口三部分组成。
rewrite实例

server  {
 ...
 rewrite  ^(/download/.*)/media/(.*)..*$  $1/mp3/$2.mp3  last;
 rewrite  ^(/download/.*)/audio/(.*)..*$  $1/mp3/$2.ra  last;
 return  403;
 ...
}

如果这些rewrite放到 “/download/” location如下所示, 那么应使用break而不是last , 使用last将循环10次匹配,然后返回 500错误:

location  /download/  {
 rewrite  ^(/download/.*)/media/(.*)..*$  $1/mp3/$2.mp3  break;
 rewrite  ^(/download/.*)/audio/(.*)..*$  $1/mp3/$2.ra  break;
 return  403;
}

对于重写后的URL(replacement)包含原请求的请求参数,原URL的?后的内容。如果不想带原请求的参数 ,可以在replacement后加一个问号。如下,我们加了一个自定义的参数user=$1,然后在结尾处放了一个问号?,把原请的参数去掉。

rewrite  ^/users/(.*)$  /show?user=$1?  last;

如果正则表达regex式中包含 “}” 或 “;”, 那么整个表达式需要用双引号或单引号包围.

rewrite_log指令

语法:rewrite_log on|off;
默认值:rewrite_log off;
作用域:http,server,location,if
开启或关闭以notice级别打印rewrite处理日志到error log文件。

nginx打开rewrite log例子

rewrite_log on;
error_log logs/xxx.error.log notice;

1.打开rewrite on
2.把error log的级别调整到 notice

set指令

语法:set variable value
默认值:none
作用域:server,location,if
定义一个变量并赋值,值可以是文本,变量或者文本变量混合体。

uninitialized_variable_warn指令

语法:uninitialized_variable_warn on | off;
默认值:uninitialized_variable_warn on
作用域:http,server,location,if

控制是否输出为初始化的变量到日志

八、NginxChsVirtualHostExample

两个虚拟主机(纯静态-html 支持) - Two Virtual Hosts, Serving Static Files

http  {
    server  {
        listen          80;
        server_name www.domain1.com;
        access_log      logs/domain1.access.log main;
        location  /  {
            index index.html;
            root  /var/www/domain1.com/htdocs;
        }
    }
    server  {
        listen          80;
        server_name www.domain2.com;
        access_log      logs/domain2.access.log main;
        location  /  {
            index index.html;
            root  /var/www/domain2.com/htdocs;
        }
    }
}

虚拟主机标准配置(简化) - A Default Catchall Virtual Host

http  {
    server  {
        listen          80  default;
        server_name _ *;
        access_log      logs/default.access.log main;
        location  /  {
            index index.html;
            root  /var/www/default/htdocs;
        }
    }
}

在父文件夹中建立子文件夹以指向子域名 - Wildcard Subdomains in a Parent Folder

这是一个添加子域名(或是当DNS已指向服务器时添加一个新域名)的简单方法。需要注意的是,我已经将FCGI配置进该文件了。如果你只想使服务器为静态文件服务,可以直接将FCGI配置信息注释掉,然后将默认主页文件变成index.html。

这个简单的方法比起为每一个域名建立一个 vhost.conf 配置文件来讲,只需要在现有的配置文件中增加如下内容:

server  {
        # Replace this port with the right one for your requirements
        # 根据你的需求改变此端口
        listen 80;  #could also be 1.2.3.4:80 也可以是1.2.3.4:80的形式
        # Multiple hostnames seperated by spaces.  Replace these as well.
        # 多个主机名可以用空格隔开,当然这个信息也是需要按照你的需求而改变的。
        server_name  star.yourdomain.com *.yourdomain.com www.*.yourdomain.com;
        #Alternately: _ *
        #或者可以使用:_ * (具体内容参见本维基其他页面)
        root  /PATH/TO/WEBROOT/$host;
        error_page  404              http://yourdomain.com/errors/404.html;
        access_log  logs/star.yourdomain.com.access.log;
        location  /  {
            root /PATH/TO/WEBROOT/$host/;
            index  index.php;
        }
        # serve static files directly
        # 直接支持静态文件 (爱月说:???从配置上看来不是直接支持啊~有问题有问题~)
        location  ~*  ^.+.(jpg|jpeg|gif|css|png|js|ico|html)$  {
            access_log        off;
            expires 30d;
        }
        location  ~  .php$  {
          # By all means use a different server for the fcgi processes if you need to
          # 如果需要,你可以为不同的FCGI进程设置不同的服务信息
          fastcgi_pass 127.0.0.1:YOURFCGIPORTHERE;
          fastcgi_index  index.php;
          fastcgi_param  SCRIPT_FILENAME  /PATH/TO/WEBROOT/$host/$fastcgi_script_name;
          fastcgi_param  QUERY_STRING $query_string;
          fastcgi_param  REQUEST_METHOD $request_method;
          fastcgi_param  CONTENT_TYPE $content_type;
          fastcgi_param  CONTENT_LENGTH $content_length;
          fastcgi_intercept_errors on;
        }
        location  ~  /.ht  {
            deny  all;
        }
 }

九、nginx反向代理配置

nginx作为web服务器一个重要的功能就是反向代理。

nginx反向代理的指令不需要新增额外的模块,默认自带proxy_pass指令,只需要修改配置文件就可以实现反向代理。

1、什么是反向代理服务器

反向代理功能是nginx的三大主要功能之一(静态web服务器、反向代理、负载均衡)。nginx一般同时做为静态web服务器和反向代理服务器,做为web服务器访问静态文件图片、css、js、html等文件,做为反向代理服务器把请求发给后端业务处理服务,如果有多个后端处理节点,会配置负载均衡功能。

反向代理服务器是一种代理服务器,用于管理从外部网络到内部网络的连接或任何特定请求。它保护、路由和管理从外部网络到内部网络、Web服务器或专用网络的流量。

(1)外网客户机:我们平时打开浏览器输入网址访问www.nginx.cn的场景中,我们的笔记本就可以理解为一个外网客户机。

(2)nginx反向代理服务:浏览器输入网址并回车后,会发起一个http请求给nginx(反向代理服务器),这个请求如果是访问静态文件,那么nginx作为web服务器直接返回请求的内容,如果是访问的后台服务逻辑,那么nginx把请求转发给后端的服务处理。

(3)内网web服务:后端的服务可以是很多种类型,LNMP环境下的php-fpm进程,Java环境下的tomcat、jetty等容器,通过程序逻辑处理http请求,生成html页面或者json串返回给客户端。对于小型应用,后端服务可以和nginx部署在同一台机器上。

2、反向代理服务器的好处

nginx反向代理重要的作用是配合upstream实现负载均衡。同时增加安全性,客户端不能直接访问后端服务,多了一个中间的屏障。提升性能,通过异步非阻塞的方式把请求传给后端,提升了并发处理能力。也可利用缓存、压缩响应提高响应速度。

3、nginx如何配置反向代理

nginx反向代理不需要编译额外的模块,默认自带proxy_pass和fastcgi_pass指令,通过在location配置块中增加指令就可以实现反向代理功能。

www.nginx.cn为例,这个网站用的wordpress程序,wordpress是php语言编写,那么需要通过php运行环境,可以选择apache的php扩展或者php-fpm环境,主流的选择是php-fpm,php-fpm设置为Unix socket模式或者ip:端口模式 。

(1)Unix socket后端服务配置

server  {
    listen  80;
    server_name www.nginx.cn nginx.cn;
    location  /app  {
       fastcgi_pass  unix:/tmp/php-cgi.sock;
    }
}

(2)ip端口后端服务配置

server  {
    listen  80;
    server_name www.nginx.cn nginx.cn;
    location  /app  {
      proxy_pass http://127.0.0.1:8080;
    }
}

4、proxy_pass和fastcgi_pass区别

对于上面介绍的两种情况下proxy_pass和fastcgi_pass可以互相替代使用,不过两者还是有区别的,从名字我们就可以看出来,fastcgi_pass是用来反向代理fastcgi协议,proxy_pass可以代理包括fastcgi协议在内的其它协议。

例如镜像一个网站,这种情况下就需要proxy_pass:

location  /{
  proxy_pass http://www.baidu.com;
}

十、nginx负载均衡配置

使用负载均衡的话,可以修改配置http节点如下:

1、设定http服务器,利用它的反向代理功能提供负载均衡支持

http  {
    #设定mime类型,类型由mime.type文件定义
    include /etc/nginx/mime.types;
    default_type    application/octet-stream;
    #设定日志格式
    access_log        /var/log/nginx/access.log;
    #省略上文有的一些配置节点
    #。。。。。。。。。。
    #设定负载均衡的服务器列表
    upstream  mysvr  {
        #weigth参数表示权值,权值越高被分配到的几率越大
        server  192.168.8.1x:3128  weight=5;
        #本机上的Squid开启3128端口,不是必须要squid
        server  192.168.8.2x:80    weight=1;
        server  192.168.8.3x:80    weight=6;
    }
    upstream  mysvr2  {
        #weigth参数表示权值,权值越高被分配到的几率越大
        server  192.168.8.x:80    weight=1;
        server  192.168.8.x:80    weight=6;
    }
    #第一个虚拟服务器
    server  {
        #侦听192.168.8.x的80端口
        listen 80;
        server_name    192.168.8.x;
        #对aspx后缀的进行负载均衡请求
        location  ~  .*.aspx$  {
            #定义服务器的默认网站根目录位置
            root /root;
            #定义首页索引文件的名称
            index index.php index.html index.htm;
            #请求转向mysvr 定义的服务器列表
            proxy_pass    http://mysvr ;
            #以下是一些反向代理的配置可删除.
            proxy_redirect off;
            #后端的Web服务器可以通过X-Forwarded-For获取用户真实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;
            #允许客户端请求的最大单文件字节数
            client_max_body_size  10m;
            #缓冲区代理缓冲用户端请求的最大字节数,
            client_body_buffer_size  128k;
            #nginx跟后端服务器连接超时时间(代理连接超时)
            proxy_connect_timeout  90;
            #连接成功后,后端服务器响应时间(代理接收超时)
            proxy_read_timeout  90;
            #设置代理服务器(nginx)保存用户头信息的缓冲区大小
            proxy_buffer_size  4k;
            #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
            proxy_buffers  4  32k;
            #高负荷下缓冲大小(proxy_buffers*2)
            proxy_busy_buffers_size  64k;
            #设定缓存文件夹大小,大于这个值,将从upstream服务器传
            proxy_temp_file_write_size  64k;    
        }
    }
}

十一、 nginx屏蔽ip

1.查找要屏蔽的ip
awk '{print $1}' nginx.access.log |sort |uniq -c|sort -n
nginx.access.log 为日志文件,
会到如下结果,前面是ip的访问次数,后面是ip,很明显我们需要把访问次数多的ip并且不是蜘蛛的ip屏蔽掉,本例当中我们屏蔽掉165.91.122.67
13610 202.112.113.192
95772 180.169.22.135
337418 219.220.141.2
558378 165.91.122.67
2.在nginx的安装目录下面,新建屏蔽ip文件,命名为blockip.conf,以后新增加屏蔽ip只需编辑这个文件即可。 加入如下内容
deny 165.91.122.67;
保存一下。

3.在nginx的配置文件nginx.conf中加入如下配置,可以放到http, server, location, limit_except语句块,需要注意相对路径,本例当中nginx.conf,blocksip.conf在同一个目录中。
include blockip.conf;

4.重启一下nginx的服务:/usr/local/nginx/nginx -s reload 就可以生效了。

高级用法:

屏蔽ip的配置文件既可以屏蔽单个ip,也可以屏蔽ip段,或者只允许某个ip或者某个ip段访问。

屏蔽单个ip访问

deny IP;

允许单个ip访问

allow IP;

屏蔽所有ip访问

deny all;

允许所有ip访问

allow all;
deny  123.0.0.0/8

屏蔽IP段即从123.45.0.1到123.45.255.254访问的命令

deny 124.45.0.0/16

屏蔽IP段即从123.45.6.1到123.45.6.254访问的命令

deny 123.45.6.0/24

如果你想实现这样的应用,除了几个IP外,其他全部拒绝,
那需要你在blockip.conf中这样写

allow  1.1.1.1;
allow  1.1.1.2;
deny all;

单独网站屏蔽IP的方法,把include blocksip.conf; 放到网址对应的在server{}语句块,所有网站屏蔽IP的方法,把include blocksip.conf; 放到http {}语句块。

十二、 nginx "403 Forbidden" 错误

nginx 的 403 Forbidden errors 表示你在请求一个资源文件但是nginx不允许你查看。
403 Forbidden 只是一个HTTP状态码,像404,200一样不是技术上的错误。
哪些场景需要返回403状态码的场景?

1.网站禁止特定的用户访问所有内容,例:网站屏蔽某个ip访问。
2.访问禁止目录浏览的目录,例:设置autoindex off后访问目录。
3.用户访问只能被内网访问的文件。

以上几种常见的需要返回 403 Forbidden 的场景。

由于服务器端的错误配置导致在不希望nginx返回403时返回403 Forbidden。

1.权限配置不正确
为了保证文件能正确执行,nginx既需要文件的读权限,又需要文件所有父目录的可执行权限。

例如,当访问/usr/local/nginx/html/image.jpg时,nginx既需要image.jpg文件的可读权限,也需要/,/usr,/usr/local,/usr/local/nginx,/usr/local/nginx/html的可以执行权限。

解决办法:设置所有父目录为755权限,设置文件为644权限可以避免权限不正确。

2.目录索引设置错误(index指令配置)

网站根目录不包含index指令设置的文件。

例如,运行PHP的网站,通常像这样配置index

index index.html index.htm index.php;

当访问该网站的时,nginx 会按照 index.html,index.htm ,index.php 的先后顺序在根目录中查找文件。如果这三个文件都不存在,那么nginx就会返回403 Forbidden。

如果index中不定义 index.php ,nginx直接返回403 Forbidden而不会去检查index.php是否存在。

同样对于如果运行jsp, py时也需要添加index.jsp,index.py到目录索引指令index中。

解决办法:添加首页文件到index指令,常见的是index.php,index.jsp,index.jsp或者自定义首页文件。

十三、nginx 502 bad gateway timeout

一朋友的nginx服务器网站打开不,出现502 bad gateway timeout。
同一台机机器上使用nginx做反向代理的服务可以正常访问。
偶然df -ah看了一下发现磁盘已经满了。

把没用的日志(du -ks *|sort -n 命令可以列出来文件间空使用情况并排序)清理一下,发现网站能正常访问了。

做个记号,给遇到同样问题的做个分析思路。

nginx+php-fpm出现502 bad gateway错误解决方法

502错误是所有用nginx跑php的运维人员不愿意看见的

nginx出现502有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端php-fpm处理有问题,nginx将正确的客户端请求发给了后端的php-fpm进程,但是因为php-fpm进程的问题导致不能正确解析php代码,最终返回给了客户端502错误。

服务器出现502的原因是连接超时 我们向服务器发送请求 由于服务器当前链接太多,导致服务器方面无法给于正常的响应,产生此类报错

因此如果你服务器并发量非常大,那只能先增加机器,然后按以下方式优化会取得更好效果;但如果你并发不大却出现502,一般都可以归结为配置问题,脚本超时问题。

1.php-fpm进程数不够用

使用 netstat -napo |grep "php-fpm" | wc -l 查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。

但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。

2. 调高调高linux内核打开文件数量

可以使用这些命令(必须是root帐号)

echo 'ulimit -HSn 65536' >> /etc/profile

echo 'ulimit -HSn 65536' >> /etc/rc.local

source /etc/profile

** 3.脚本执行时间超时**

如果脚本因为某种原因长时间等待不返回 ,导致新来的请求不能得到处理,可以适当调小如下配置。

nginx.conf里面主要是如下

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

php-fpm.conf里如要是如下

request_terminate_timeout = 10s

4.缓存设置比较小

修改或增加配置到nginx.conf

proxy_buffer_size 64k;
proxy_buffers  512k;
proxy_busy_buffers_size 128k;

5. recv() failed (104: Connection reset by peer) while reading response header from upstream

可能的原因机房网络丢包或者机房有硬件防火墙禁止访问该域名

但最重要的是程序里要设置好超时,不要使用php-fpm的request_terminate_timeout,

最好设成request_terminate_timeout=0;

因为这个参数会直接杀掉php进程,然后重启php进程,这样前端nginx就会返回104: Connection reset by peer。这个过程是很慢,总体感觉就是网站很卡。

说一千道一万最重要的就是程序里控制好超时,gethostbyname、curl、file_get_contents等函数的都要设置超时时间。

另一个就是多说,这个东西是增加了网站的交互性,但是使用的多了反应就慢了,如果你网站超时且使用了多说是,可以关闭它。

上一篇下一篇

猜你喜欢

热点阅读