# Nginx简介及环境准备

原文地址:https://www.yuque.com/wukong-zorrm/cql6cz/ofesua (opens new window)

# 1.nginx简介

Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。

# 2.环境准备

本课程的重点是nginx的使用,为了方便大家学习,而不是把大量时间花费在环境搭建过程中,本课程提供了虚拟机镜像,基于Centos7,网盘链接: https://pan.baidu.com/s/1NmCR-vdAcZLouRRn9V1yTA 密码: 1b60

  • 使用说明:

用户名/密码:root/123456,课程中使用的环境和应用放置在/home目录下

目录 简介 说明
AdminLTE-3.2.0 静态web后台管理系统 静态web的配置演示
apps/ruoyi-admin.jar 若依后台管理系统,基于springboot 方向代理演示
apache-tomcat-8.5.81apps/ruoyi-admin.war javaweb服务器 动静分离演示
sql/ry_20210924.sqlsql/quartz.sql 数据库初始化脚本 创建若依后台数据库
mysql5.7 数据库 用户名/密码:root/123456
open-JDK 1.8 java运行环境 已安装

# 3.下载地址

如果不需要虚拟机,大家也可以自行下载安装。

  • AdminLTE

官方网址:https://adminlte.io/

源码下载:https://codeload.github.com/ColorlibHQ/AdminLTE/tar.gz/refs/tags/v3.2.0

一个静态web后台管理系统

  • RuoYi

一个基于Spring Boot的后台管理系统

说明文档:http://doc.ruoyi.vip/ruoyi/

源码下载:https://codeload.github.com/yangzongzhuan/RuoYi/zip/refs/tags/v4.7.4

也可以从网盘中获取打包好的ruoyi-admin.jar和ruoyi-admin.war

网盘链接: https://pan.baidu.com/s/1NmCR-vdAcZLouRRn9V1yTA 密码: 1b60

  • open-JDK 1.8
yum install java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64
  • tomcat 8.5

官方网址:https://tomcat.apache.org/

下载地址:https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.81/bin/apache-tomcat-8.5.81.tar.gz

  • mysql 5.7
cat > /etc/yum.repos.d/mysql-community.repo<<EOF
[mysql57-community]
name=MySQL 5.7 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/\$releasever/\$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2022
       file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
EOF
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

yum install mysql-community-server

systemctl start mysqld

systemctl status mysqld

grep 'temporary password' /var/log/mysqld.log
#A temporary password is generated for root@localhost: m9cpkdkLEX

mysql -uroot -p

ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';

修改简单的密码

SHOW VARIABLES LIKE 'validate_password%';

set GLOBAL validate_password_policy = LOW;
set GLOBAL validate_password_length = 6;

ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';

# 1.安装与启动

环境准备:

  • Centos 7.4+
  • 可访问联网
  • 关闭防火墙
sudo systemctl stop firewalld
sudo systemctl disable firewalld

# 1.使用yum安装

sudo yum install yum-utils net-tools
cat > /etc/yum.repos.d/nginx.repo << EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
sudo yum install nginx

# 2.常用命令

nginx 

#立即停止
nginx -s stop

#执行完当前请求再停止
nginx -s quit

#重新加载配置文件,相当于restart
nginx -s reload

#将日志写入一个新的文件
nginx -s reopen

#测试配置文件
nginx -t

日志位于/var/log/nginx/

# 3.使用systemctl启动、停止、重新加载

注意:在centos 7中,用systemctl启动nginx可能出现如下错误,

nginx: [emerg] bind() to 0.0.0.0:8000 failed (13: Permission denied)

这是由于selinux的安全策略引起的。解决方法如下:

  • setenforce 0 (临时)
  • 修改/etc/selinux/config,设置SELINUX=disabled (永久有效,需重启)
systemctl start nginx

systemctl status nginx

#产看日志
journalctl -xe

systemctl stop nginx

systemctl reload nginx

#配置开机启动
systemctl enable nginx

# 4.配置文件

配置文件位于 /etc/nginx/nginx.conf , 下列命令会引用/etc/nginx/conf.d目录下所有的.conf文件,这样可以保持主配置文件的简洁,同时配个多个.conf文件方便区分,增加可读性。

include /etc/nginx/conf.d/*.conf;

默认配置/etc/nginx/conf.d/default.conf

server {
    listen       80; #监听端口
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html; #根目录
        index  index.html index.htm; #首页
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

# 5.配置文件结构

http {

  server{#虚拟主机
     
    location {
      listen 80;
      server_name localhost;
    }
    location {
       
    }
      
  }

  server{
  
  }

}

参考文档:

https://nginx.org/en/linux_packages.html

https://nginx.org/en/docs/beginners_guide.html#control

# 2.静态网页

# 静态网页配置

配置一个静态的AdminLTE后台管理系统。

AdminLTE官方网址:https://adminlte.io/

源码下载:https://codeload.github.com/ColorlibHQ/AdminLTE/tar.gz/refs/tags/v3.2.0

配置文件示例:

server{
  
    listen 8000;
    server_name localhost;
    
    location / {
        root /home/AdminLTE-3.2.0;
        index index.html index2.html index3.html;
    }
  
}

虚拟主机server通过listen和server_name进行区分,如果有多个server配置,listen + server_name 不能重复。

# listen

监听可以配置成IP端口IP+端口

listen 127.0.0.1:8000; 
listen 127.0.0.1;( 端口不写,默认80 ) 
listen 8000; 
listen *:8000; 
listen localhost:8000;

# server_name

server_name主要用于区分,可以随便起。

也可以使用变量$hostname配置成主机名。

或者配置成域名:example.org www.example.org *.example.org

如果多个server的端口重复,那么根据域名或者主机名去匹配 server_name 进行选择。

下面的例子中:

curl http://localhost:80`会访问`/usr/share/nginx/html
curl http://nginx-dev:80`会访问`/home/AdminLTE-3.2.0
# curl http://localhost:80 会访问这个
server {
    listen       80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

 # curl http://nginx-dev:80 会访问这个
server{
    listen 80;
    server_name nginx-dev;#主机名
    
    location / {
        root /home/AdminLTE-3.2.0;
        index index.html index2.html index3.html;
    }
  
}

# location

/请求指向 root 目录

location 总是从/目录开始匹配,如果有子目录,例如/css,他会指向/static/css

location /css {
  root /static;
}

参考文档:

https://nginx.org/en/docs/beginners_guide.html

https://nginx.org/en/docs/http/ngx_http_core_module.html#listen

https://nginx.org/en/docs/http/server_names.html

# 3.HTTP反向代理

# 1.正向代理与反向代理

  • 正向代理

客户端代理转发请求称为正向代理。例如VPN。

img

  • 反向代理

服务器端代理转发请求称为反向代理。例如nginx

img

# 2.配置代理服务

img

RuoYi是一个基于Spring Boot的后台管理系统,ruoyi-admin.jar可以从网盘中获取

网盘链接: https://pan.baidu.com/s/1NmCR-vdAcZLouRRn9V1yTA 密码: 1b60

也可以根据官网文档(http://doc.ruoyi.vip/ruoyi/),自己编译打包。

源码下载:https://codeload.github.com/yangzongzhuan/RuoYi/zip/refs/tags/v4.7.4

启动ruoyi后台服务,端口为8088;

java -jar ruoyi-admin.jar

nginx配置文件:

server {
  
  listen 8001;
  
  server_name ruoyi.localhost;
  
  location / {
    proxy_pass http://localhost:8088;
  }

}

proxy_pass配置说明:

location /some/path/ {
    proxy_pass http://localhost:8080;
}
  • 如果proxy-pass的地址只配置到端口,不包含/或其他路径,那么location将被追加到转发地址中

如上所示,访问 http://localhost/some/path/page.html 将被代理到 http://localhost:8080/some/path/page.html

location /some/path/ {
    proxy_pass http://localhost:8080/zh-cn/;
}
  • 如果proxy-pass的地址包括/或其他路径,那么/some/path将会被替换,如上所示,访问 http://localhost/some/path/page.html 将被代理到 http://localhost:8080/zh-cn/page.html。‎

# 3.设置代理请求headers

‎用户可以重新定义或追加header信息传递给后端 (opens new window)‎服务器。可以包含文本、变量及其组合。默认情况下,仅重定义两个字段:‎

proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;

由于使用反向代理之后,后端服务无法获取用户的真实IP,所以,一般反向代理都会设置以下header信息。

location /some/path/ {
    #nginx的主机地址
    proxy_set_header Host $http_host;
    #用户端真实的IP,即客户端IP
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_pass http://localhost:8088;
}

常用变量的值:

$host:nginx主机IP,例如192.168.56.105

$http_host:nginx主机IP和端口,192.168.56.105:8001

$proxy_host:localhost:8088,proxy_pass里配置的主机名和端口

$remote_addr:用户的真实IP,即客户端IP。

# 4.非HTTP代理

如果要将请求传递到非 HTTP 代理服务器,可以使用下列指令:

参考文档:

https://nginx.org/en/docs/beginners_guide.html

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

# 4.动静分离

# 动静分离的好处

Apache Tocmat 严格来说是一款java EE服务器,主要是用来处理 servlet请求。处理css、js、图片这些静态文件的IO性能不够好,因此,将静态文件交给nginx处理,可以提高系统的访问速度,减少tomcat的请求次数,有效的给后端服务器降压。

# 分离静态文件

img

RuoYi是一个基于Spring Boot的后台管理系统,ruoyi-admin.war可以从网盘中获取

网盘链接: https://pan.baidu.com/s/1NmCR-vdAcZLouRRn9V1yTA 密码: 1b60

也可以根据官网文档(http://doc.ruoyi.vip/ruoyi/),自己编译打包。

源码下载:https://codeload.github.com/yangzongzhuan/RuoYi/zip/refs/tags/v4.7.4

部署ruoyi-admin.war

mv /home/apps/ruoyi-admin.war /home/apache-tomcat-8.5.81/webapps/ROOT.war
rm -rf /home/apache-tomcat-8.5.81/webapps/ROOT
/home/apache-tomcat-8.5.81/bin/startup.sh

部署完成后,对项目目录稍作调整

cd /home/apache-tomcat-8.5.81/webapps/ROOT
mv WEB-INF/classes/static/i18n  WEB-INF/classes/templates/i18n 
mv WEB-INF/classes/static /home/www/

修改application.yml

messages:
    # 国际化资源文件路径 
    # 将 static/i18n/messages 修改为 templates/i18n/messages
    basename: templates/i18n/messages

静态文件目录说明:

除了js、css、图片文件之外,还有字体文件和一个ie提示页面。

img

server{


  location / {
    proxy_pass http://localhost:8080/;
  }
  
  location = /html/ie.html {
    root  /home/www/static;
  }
  
  location ^~ /fonts/ {
   
    root  /home/www/static;
  }
  
  location ~ \.(css|js|png|jpg|gif|ico) {
    root /home/www/static;
}

# location 修饰符

  • location可以使用修饰符或正则表达式

修饰符:

= 等于,严格匹配 ,匹配优先级最高。

^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其它 location。优先级第二高。

~ 区分大小写

~* 不区分大小写

  • 优先级

优先级从高到低依次为:。

  1. 精确匹配(=)
  2. 前缀匹配(^~)
  3. 正则匹配(~和~*)
  4. 不写
location ^~ /images/ {
    proxy_pass http://localhost:8080;
}

location ~ \.jpg {
    proxy_pass http://localhost:8080;
}

如上所示:

/images/1.jpg`代理到 `http://localhost:8080/images/1.jpg
/some/path/1.jpg` 代理到`http://localhost:8080/some/path/1.jpg

参考文档:

https://nginx.org/en/docs/beginners_guide.html

https://nginx.org/en/docs/http/ngx_http_core_module.html#location

https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/

# 5.缓冲(buffer)和缓存(cache)

# 缓冲(buffer)

缓冲一般放在内存中,如果不适合放入内存(比如超过了指定大小),则会将响应写入磁盘临时文件中。

启用缓冲后,nginx先将后端的请求响应(response)放入缓冲区中,等到整个响应完成后,再发给客户端。

img

客户端往往是用户网络,情况复杂,可能出现网络不稳定,速度较慢的情况。

而nginx到后端server一般处于同一个机房或者区域,网速稳定且速度极快。

img

如果禁用了缓冲,则在客户端从代理服务器接收响应时,响应将同步发送到客户端。对于需要尽快开始接收响应的快速交互式客户端,此行为可能是可取的。

这就会带来一个问题:因为客户端到nginx的网速过慢,导致nginx只能以一个较慢的速度将响应传给客户端;进而导致后端server也只能以同样较慢的速度传递响应给nginx,造成一次请求连接耗时过长。

在高并发的情况下,后端server可能会出现大量的连接积压,最终拖垮server端。

img

开启代理缓冲后,nginx可以用较快的速度尽可能将响应体读取并缓冲到本地内存或磁盘中,然后同时根据客户端的网络质量以合适的网速将响应传递给客户端。

这样既解决了server端连接过多的问题,也保证了能持续稳定的像客户端传递响应。

使用proxy_buffering (opens new window)启用和禁用缓冲,nginx默认为 on 启用缓冲,若要关闭,设置为 off 。

proxy_buffering off;

proxy_buffers (opens new window) 指令设置每个连接读取响应的缓冲区的大小数量 。默认情况下,缓冲区大小等于一个内存页,4K 或 8K,具体取决于操作系统。

来自后端服务器响应的第一部分存储在单独的缓冲区中,其大小通过 proxy_buffer_size (opens new window) 指令进行设置,此部分通常是相对较小的响应headers,通常将其设置成小于默认值。

location / {
    proxy_buffers 16 4k;
    proxy_buffer_size 2k;
    proxy_pass http://localhost:8088;
}

如果整个响应不适合存到内存里,则将其中的一部分保存到磁盘上的‎‎临时文件中‎‎。

‎proxy_max_temp_file_size‎ (opens new window)‎设置临时文件的最大值。

‎proxy_temp_file_write_size‎ (opens new window)‎设置一次写入临时文件的大小。

# 缓存(cache)

启用缓存后,nginx将响应保存在磁盘中,返回给客户端的数据首先从缓存中获取,这样子相同的请求不用每次都发送给后端服务器,减少到后端请求的数量。

img

启用缓存,需要在http上下文中使用 proxy_cache_path (opens new window) 指令,定义缓存的本地文件目录,名称和大小。

缓存区可以被多个server共享,使用proxy_cache (opens new window) 指定使用哪个缓存区。

http {
    proxy_cache_path /data/nginx/cache keys_zone=mycache:10m;
    server {
        proxy_cache mycache;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

缓存目录的文件名是 proxy_cache_key (opens new window) 的MD5值。

例如:/data/nginx/cache/**c**/**29**/b7f54b2df7773722d382f4809d650**29c**

proxy_cache_key (opens new window) 默认设置如下:

proxy_cache_key $scheme$proxy_host$uri$is_args$args;

也可以自定义缓存的键,例如

proxy_cache_key "$host$request_uri$cookie_user";

缓存不应该设置的太敏感,可以使用proxy_cache_min_uses (opens new window)设置相同的key的请求,访问次数超过指定数量才会被缓存。

proxy_cache_min_uses 5;

默认情况下,响应无限期地保留在缓存中。仅当缓存超过最大配置大小时,按照时间删除最旧的数据。

# 示例

proxy_cache_path /var/cache/nginx/data keys_zone=mycache:10m;

server {

    listen 8001;
    server_name ruoyi.localhost;
    
    location / {
        #设置buffer
        proxy_buffers 16 4k;
        proxy_buffer_size 2k;
        proxy_pass http://localhost:8088;        

    }


    location ~ \.(js|css|png|jpg|gif|ico) {
        #设置cache
        proxy_cache mycache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404      1m;
        proxy_cache_valid any 5m;

        proxy_pass http://localhost:8088;  
    }

    location = /html/ie.html {

        proxy_cache mycache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404      1m;
        proxy_cache_valid any 5m;

        proxy_pass http://localhost:8088;  
    }

    location ^~ /fonts/ {

        proxy_cache mycache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404      1m;
        proxy_cache_valid any 5m;

        proxy_pass http://localhost:8088;  
    }

}

参考文档:

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size

https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path

https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/

# 6.负载均衡

跨多个应用程序实例的负载平衡是一种常用技术,用于优化资源利用率、最大化吞吐量、减少延迟和确保容错配置。‎使用nginx作为非常有效的HTTP负载平衡器,将流量分配到多个应用程序服务器,可以提升Web应用程序的性能,提高扩展性和可靠性。

# 配置服务组

img

使用 upstream定义一组服务 。

注意:upstream 位于 http上下文中,与server 并列,不要放在server中。

upstream ruoyi-apps {
    #不写,采用轮循机制
    server localhost:8080;
    server localhost:8088;
  
}

server {
  
  listen 8003;
  server_name ruoyi.loadbalance;
  
  location / {
    proxy_pass http://ruoyi-apps;
  }

}

# 负载均衡策略

# 1.轮循机制(round-robin)

默认机制,以轮循机制方式分发。

# 2.最小连接 (opens new window)(least-connected )

将下一个请求分配给活动连接数最少的服务器(较为空闲的服务器)。‎

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}

请注意,使用轮循机制或最少连接的负载平衡,每个客户端的请求都可能分发到不同的服务器。不能保证同一客户端将始终定向到同一服务器。‎

# 3.ip-hash (opens new window)

客户端的 IP 地址将用作哈希键,来自同一个ip的请求会被转发到相同的服务器。

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}

此方法可确保来自同一客户端的请求将始终定向到同一服务器,除非此服务器不可用。‎

# ‎4.hash (opens new window)

通用hash,允许用户自定义hash的key,key可以是字符串、变量或组合。

例如,key可以是配对的源 IP 地址和端口,也可以是 URI,如以下示例所示:‎

upstream backend {
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

请注意:基于 IP 的哈希算法存在一个问题,那就是当有一个上游服务器宕机或者扩容的时候,会引发大量的路由变更,进而引发连锁反应,导致大量缓存失效等问题。

consistent参数启用 ‎‎ketama‎ (opens new window)‎ 一致哈希算法,如果在上游组中添加或删除服务器,只会重新映射部分键,从而最大限度地减少缓存失效。‎

假设我们基于 key 来做 hash,现在有 4 台上游服务器,如果 hash 算法对 key 取模,请求根据用户定义的哈希键值均匀分布在所有上游服务器之间。。

img当有一台服务器宕机的时候,就需要重新对 key 进行 hash,最后会发现所有的对应关系全都失效了,从而会引发缓存大范围失效。

img

img

# 5.‎随机‎ (opens new window)‎ (random)

每个请求都将传递到随机选择的服务器。

two是可选参数,NGINX 在考虑服务器权重的情况下随机选择两台服务器,然后使用指定的方法选择其中一台,默认为选择连接数最少(least_conn‎)的服务器。

upstream backend {
    random two least_conn;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    server backend4.example.com;
}

# 6.权重(weight)

img

upstream my-server {
  
    server performance.server weight=3;
    server app1.server;
    server app2.server;

}

‎如上所示,每 5 个新请求将按如下方式分布在应用程序实例中:3 个请求将定向到performance.server,一个请求将转到app1.server,另一个请求将转到app2.server。‎

# 7.健康检查

在反向代理中,如果后端服务器在某个周期内响应失败次数超过规定值,nginx会将此服务器标记为失败,并在之后的一个周期不再将请求发送给这台服务器。‎

通过fail_timeout‎ (opens new window)‎ 来设置检查周期,默认为10秒。

通过max_fails‎ (opens new window)来设置检查失败次数,默认为1次。‎

‎在以下示例中,如果NGINX无法向服务器发送请求或在30秒内请求失败次数超过3次,则会将服务器标记为不可用30秒。

upstream backend {
  server backend1.example.com;
  server backend2.example.com max_fails=3 fail_timeout=30s; 
} 

参考文档:

https://nginx.org/en/docs/http/load_balancing.html

https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

# 7.HTTPS配置

HTTPS 协议是由HTTP 加上TLS/SSL 协议构建的可进行加密传输、身份认证的网络协议,主要通过数字证书、加密算法、非对称密钥等技术完成互联网数据传输加密,实现互联网传输安全保护。

# 生成证书

openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

# 配置ssl

server {
    listen              443 ssl;
    server_name         ruoyi.https;
    ssl_certificate     /home/ssl/server.crt;
    ssl_certificate_key /home/ssl/server.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
  
    location / {
        proxy_pass http://localhost:8088;
    }
}

如果设置了密码,需要加上

server{
  ……
  ssl_password_file   /home/ssl/cert.pass;
  ……
} 

# https优化

SSL 操作会消耗额外的 CPU 资源。CPU 占用最多的操作是 SSL 握手。有两种方法可以最大程度地减少每个客户端的这些操作数:

  • 使保持活动连接能够通过一个连接发送多个请求
  • 重用 SSL 会话参数以避免并行连接和后续连接的 SSL 握手

会话存储在工作进程之间共享并由 ssl_session_cache (opens new window) 指令配置的 SSL 会话缓存中。一兆字节的缓存包含大约 4000 个会话。默认缓存超时为 5 分钟。可以使用 ssl_session_timeout (opens new window) 指令增加此超时。以下是针对具有 10 MB 共享会话缓存的多核系统优化的示例配置:

ssl_session_cache   shared:SSL:10m;
ssl_session_timeout 10m;

参考文档:

http://nginx.org/en/docs/http/configuring_https_servers.html

https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-http/

# 8.TCP反向代理

# 1.stream

#HTTP代理
http {
  server {
    listen 8002;
    proxy_pass http://localhost:8080/;
  }
}

#TCP代理
stream {
  server {
    listen 13306;
    proxy_pass localhost:3306;
  }
}

# 2.tcp负载均衡

stream {
  
  upstream backend-mysql {
  
    server localhost:3306;
    server localhost:3307;
    
    keepalive 8;
  }
  
  server {
    listen 13306;
    proxy_pass backend-mysql;
  }
}

使用**keepalive**定义连接池里空闲连接的数量。

**keepalive_timeout** 默认60s。如果连接池里的连接空闲时间超过这个值,则连接关闭。

在最简单的 HTTP 实现中,客户端打开新连接,写入请求,读取响应,然后关闭连接以释放关联的资源。

img

在客户端读取响应后,保持连接处于打开状态,因此可以将其重新用于后续请求。

img

使用 keepalive (opens new window) 指令启用从 NGINX Plus 到上游服务器的保持活动连接,定义在每个工作进程的缓存中保留的与上游服务器的空闲保持活动连接的最大数量。当超过此数字时,将关闭最近最少使用的连接。如果没有 keepalives,您将增加更多的开销,并且连接和临时端口都效率低下。

现代 Web 浏览器通常会打开 6 到 8 个保持连接。

参考文档:

https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/

https://www.nginx.com/blog/http-keepalives-and-web-performance/

https://www.nginx.com/blog/overcoming-ephemeral-port-exhaustion-nginx-plus/

# 9.重写(return和rewrite)

nginx有两个重写指令:returnrewrite

# return

服务端停止处理并将状态码status code返回给客户端

return *code* *URL*
return *code* *text*
return *code*
return *URL*

# 强制所有请求使用Https

错误写法

server {

    listen 8003;
    server_name ruoyi.loadbalance;

    return 301 https://localhost:8004;
}

正确写法

server {

    listen 8003;
    server_name ruoyi.loadbalance;

    return 301 https://192.168.56.105:8004;
}

# 转发和重定向

转发是服务端行为,重定向是客户端行为。

# 转发

发向代理proxy_pass属于转发,浏览器的访问栏输入的地址不会发生变化。

img

# 重定向

return,rewrite属于重定向,在客户端进行。浏览器的访问栏输入的地址会发生变化。

img

域名迁移,不让用户收藏的链接或者搜索引擎的链接失效

将请求从 www.old-name.com old-name.com 永久重定向到 www.new-name.com,包含http和https请求

server {
    listen 80;
    listen 443 ssl;
    server_name www.old-name.com old-name.com;
    return 301 $scheme://www.new-name.com$request_uri;
}

由于捕获了域名后面的 URL 部分,因此,如果新旧网站之间存在一对一的页面对应关系(例如,www.new-name.com/about 具有与 www.old-name.com/about 相同的基本内容),则此重写是合适的。如果除了更改域名之外还重新组织了网站,则通过省略以下内容,将所有请求重定向到主页可能会更安全

server {
    listen 80;
    listen 443 ssl;
    server_name www.old-name.com old-name.com;
    return 301 $scheme://www.new-name.com;
}

添加www

# add 'www'
server {
    listen 80;
    listen 443 ssl;
    server_name domain.com;
    return 301 $scheme://www.domain.com$request_uri;
}

# 状态码

  • 2xx 成功

  • 3xx 表示重定向

    • 301 永久重定向
    • 302 临时重定向
  • 4xx 请求地址出错

    • 403 拒绝请求
    • 404 请求找不到
  • 5xx 服务器内部错误

# rewrite

‎如果指定的正则表达式与请求 URI 匹配,则 URI 将按照字符串中的指定进行更改。指令按其在配置文件中出现的先后顺序执行。

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

上面是使用该指令的示例 NGINX 重写规则。它匹配以字符串 /download 开头的 URL,然后在路径后面的某个位置包含 /media/ 或 /audio/ 目录。它将这些元素替换为 /mp3/,并添加相应的文件扩展名,.mp3.ra。和 变量捕获未更改的路径元素。例如,/download/cdn-west/media/file1 变成了 /download/cdn-west/mp3/file1.mp3。如果文件名上有扩展名(如 .flv),则表达式会将其剥离,并将其替换为**.mp3**。

如果字符串包含新的请求参数,则以前的请求参数将追加到这些参数之后。如果不需要这样做,则在替换字符串的末尾放置一个问号可以避免附加它们,例如:replacement

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

# last与break

last:如果当前规则不匹配,停止处理后续rewrite规则,使用重写后的路径,重新搜索location及其块内指令

break:如果当前规则不匹配,停止处理后续rewrite规则,执行{}块内其他指令

# 不使用last和break

在root /home/AdminLTE-3.2.0/pages下创建一个1.txt,里面内容是this is a file

server {

    listen 8000;
    server_name nginx-dev;

    rewrite_log on;

    location / {
        rewrite ^/old/(.*) /new/$1;
        rewrite ^/new/(.*) /pages/$1;
        #根目录
        root /home/AdminLTE-3.2.0;
        #首页
        index index.html index2.html index3.html;
    }

    location  /pages/1.txt {
        return 200 "this is rewrite test!";
    }

}

默认按顺序执行。

访问 http://192.168.56.105:8000/old/1.txt

结果:this is rewrite test!

日志:

[notice] 26837#26837: *1181 "^/old/(.*)" matches "/old/1.txt", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26837#26837: *1181 rewritten data: "/new/1.txt", args: "", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26837#26837: *1181 "^/new/(.*)" matches "/new/1.txt", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26837#26837: *1181 rewritten data: "/pages/1.txt", args: "", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"

# 使用break

访问 http://192.168.56.105:8000/old/1.txt

1.匹配到了rewrite ^/old/(.*) /new/$1

2.**break**指令不执行后续的rewrite规则,以新的/new/1.txt路径去执行块内的其他指令

  1. root目录下寻找文件, 由于不再村/home/AdminLTE-3.2.0/new/1.txt这个文件,返回404
server {

    listen 8000;
    server_name nginx-dev;

    rewrite_log on;

    location / {
        rewrite ^/old/(.*) /new/$1 break;
        rewrite ^/new/(.*) /pages/$1;
        #根目录
        root /home/AdminLTE-3.2.0;
        #首页
        index index.html index2.html index3.html;
    }

    location  /pages/1.txt {
        return 200 "this is rewrite test!";
    }

}

访问 http://192.168.56.105:8000/old/1.txt

结果:

img

访问日志:

[notice] 26772#26772: *1179 "^/old/(.*)" matches "/old/1.txt", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26772#26772: *1179 rewritten data: "/new/1.txt", args: "", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[error] 26772#26772: *1179 open() "/home/AdminLTE-3.2.0/new/1.txt" failed (2: No such file or directory), client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"

# 使用last

访问 http://192.168.56.105:8000/old/1.txt

1.匹配到了rewrite ^/old/(.*) /new/$1

2.**last**指令不执行后续的rewrite规则,以新的/new/1.txt路径去匹配location

3.先匹配到location /, 有匹配到location里的rewrite ^/new/(.*) /pages/$1规则,重定向到

/pages/1.txt

4.匹配到了location /pages/1.txt ,于是返回了this is rewrite test!

server {

    listen 8000;
    server_name nginx-dev;

    rewrite_log on;

    location / {
        rewrite ^/old/(.*) /new/$1 last;
        rewrite ^/new/(.*) /pages/$1;
        #根目录
        root /home/AdminLTE-3.2.0;
        #首页
        index index.html index2.html index3.html;
    }

    location  /pages/1.txt {
        return 200 "this is rewrite test!";
    }

}

访问 http://192.168.56.105:8000/old/1.txt

结果:this is rewrite test!

日志:

[notice] 26969#26969: *1185 "^/old/(.*)" matches "/old/1.txt", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26969#26969: *1185 rewritten data: "/new/1.txt", args: "", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26969#26969: *1185 "^/old/(.*)" does not match "/new/1.txt", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26969#26969: *1185 "^/new/(.*)" matches "/new/1.txt", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"
[notice] 26969#26969: *1185 rewritten data: "/pages/1.txt", args: "", client: 192.168.56.1, server: nginx-dev, request: "GET /old/1.txt HTTP/1.1", host: "192.168.56.105:8000"

参考文档:

https://www.nginx.com/blog/creating-nginx-rewrite-rules/

https://nginx.org/en/docs/http/ngx_http_rewrite_module.html (opens new window)

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

# 10.其他常见指令

# gzip压缩

压缩响应通常会显著减小传输数据的大小。但是,由于压缩发生在运行时,因此它还会增加相当大的处理开销,从而对性能产生负面影响。NGINX在将响应发送到客户端之前执行压缩,但如果后端服务器已经对内容进行了压缩,则nginx不会再压缩。

若要启用压缩,请在参数中包含 gzip (opens new window) 指令。

gzip on; 
gzip_types text/plain application/xml; 
gzip_min_length 1000; 

默认情况下,NGINX仅使用压缩MIME类型是text/html的响应。若要使用其他 MIME 类型压缩响应,可以使用 gzip_types (opens new window) 指令并列出其他类型。

若要指定压缩响应的最小长度,请使用 gzip_min_length (opens new window) 指令。默认值为 20 个字节(此处调整为 1000)。

# sendfile

默认情况下,NGINX处理文件传输本身,并在发送之前将文件复制到缓冲区中。启用 sendfile (opens new window) 指令可消除将数据复制到缓冲区的步骤,直接将一个文件复制到另一个文件。

启用sendfile,类似Java中的零拷贝(zero copy)

location /download {
  sendfile           on;
  tcp_nopush         on; 
  #... 
} 

tcp_nopush (opens new window) 指令与 sendfile (opens new window) 指令一起使用。这使NGINX能够在获得数据块后立即在一个数据包中发送HTTP响应标头。

# try_files

try_files (opens new window)指令可用于检查指定的文件或目录是否存在;如果不存在,则重定向到指定位置。

如下,如果原始URI对应的文件不存在,NGINX将内部重定向到/www/data/images/default.gif

server {
    root /www/data;

    location /images/ {
        try_files $uri /images/default.gif;
    }
}

最后一个参数也可以是状态代码(状态码之前需要加上等号)。

在下面的示例中,如果指令的所有参数都无法解析为现有文件或目录,则会返回404错误。

location / {
    try_files $uri $uri/ $uri.html =404;
}

在下一个示例中,如果原始 URI 和附加尾随斜杠的 URI 都没有解析到现有文件或目录中,则请求将重定向到命名位置,该位置会将其传递到代理服务器。

location / {
    try_files $uri $uri/ @backend;
}

location @backend {
    proxy_pass http://backend.example.com;
}

# error_page

为错误指定显示的页面。值可以包含变量。

error_page 404             /404.html; 
error_page 500 502 503 504 /50x.html;

参考文档:

https://docs.nginx.com/nginx/admin-guide/web-server/compression/

https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/

# 11.推荐写法及注意事项

# 一、推荐写法

# 1.重复的配置可继承自父级

例如:

server {
  server_name www.example.com;
  
  location / {
    root /var/www/nginx-default/;
    # [...]
  }
  location /foo {
    root /var/www/nginx-default/;
    # [...]
  }
  location /bar {
    root /some/other/place;
  # [...]
  }
}

推荐写法

server {
    server_name www.example.com;
    root /var/www/nginx-default/;
    
    location / {
        # root继承父级配置
        # [...]
    }
    location /foo {
        # root继承父级配置
        # [...]
    }
    location /bar {
        # 覆盖
        root /some/other/place;
        # [...]
    }
}

这样在添加新的location时,可以避免重复配置。

# 2.不要将所有请求都代理到后端服务器

不推荐:

location / {
    proxy_pass http://localhost:8088;        
}

考虑到很多请求是访问静态内容(如图片,css,javascript等文件),可以使用缓存或者配置静态目录来减少发送到后端的请求数量,这样可以减小后端服务器的开销。

server {

    listen 8002;
    server_name ruoyi.tomcat;
    root /home/www/static;

    location / {
        try_files $uri $uri/ @proxy;
    }

    location @proxy {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://localhost:8080;
    }
  
}

# 3.若非必要,不要缓存动态请求,只缓存静态文件

nginx关于缓存的指令非常多

proxy_cache (opens new window)proxy_cache_background_update (opens new window)proxy_cache_bypass (opens new window)proxy_cache_convert_head (opens new window)proxy_cache_key (opens new window)proxy_cache_lock (opens new window)proxy_cache_lock_age (opens new window)proxy_cache_lock_timeout (opens new window)proxy_cache_max_range_offset (opens new window)proxy_cache_methods (opens new window)proxy_cache_min_uses (opens new window)proxy_cache_path (opens new window)proxy_cache_purge (opens new window)proxy_cache_revalidate (opens new window)proxy_cache_use_stale (opens new window)proxy_cache_valid (opens new window)proxy_no_cache (opens new window)

由于nginx服务端缓存非常复杂,在使用缓存的时候,我们要清楚的知道在什么条件下,哪些文件会被缓存。

在配置文件中,最好能够清晰的指定哪些文件使用缓存。

# 4.检查文件是否存在使用try_files代替if -f

不推荐用法:

server {
    root /var/www/example.com;
    location / {
        if (!-f $request_filename) {
            break;
        }
    }
}

推荐用法:

server {
    root /var/www/example.com;
    location / {
        try_files $uri $uri/ /index.html;
    }
}

# 5.在重写路径中包含http://或https://

#推荐写法
rewrite ^ http://example.com permanent; 

#不推荐的写法
rewrite ^ example.com permanent; 

# 6.保持重写规则简单干净

例如下面的这个例子可以变得更简单易懂。

#复杂的写法
rewrite ^/(.*)$ http://example.com/$1 permanent; 

#简单有效的写法
rewrite ^ http://example.com$request_uri? permanent; 
return 301 http://example.com$request_uri; 

# 二、注意事项

# 1.正确的配置未生效,请清除浏览器缓存

当你确定修改的配置的正确的,但是未生效,请清除浏览器缓存或者禁用浏览器缓存。

# 2.在HTTPS中不启用 SSLv3

由于 SSLv3 中存在 POODLE 漏洞,建议不要在启用了 SSL 的站点中使用 SSLv3。您可以使用以下行非常轻松地禁用 SSLv3,并仅提供 TLS 协议:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

# 3.不要将 root 目录配置成 //root

错误用法

server {
  #错误用法
  root /;
  
  location /project/path {
    #错误用法
    root /root;
  }
}

# 4.谨慎使用chmod 777

这可能是解决问题最简单的方式,同时也说明,你没有真的弄清楚哪里出了问题。

可以使用namei -om /path/to/check显示路径上的所有权限,并找到问题的根本原因。

# 5.不要将部署的项目拷贝到默认目录下

升级或更新nginx的时候,默认目录可能被覆盖。

参考文档:

https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/

https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/

# 12.Nginx配置文件详解

下面是nginx.conf文件(配置文件)的含注释详解。

#定义Nginx运行的用户和用户组
user www www;
#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;
 
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /usr/local/nginx/logs/error.log info;
#进程pid文件
pid /usr/local/nginx/logs/nginx.pid;
#指定进程可以打开的最大描述符:数目
#工作模式与连接数上限
#这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
#现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。
#这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。
worker_rlimit_nofile 65535;
events
{
    #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型
    #是Linux 2.6以上版本内核中的高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。
    #补充说明:
    #与apache相类,nginx针对不同的操作系统,有不同的事件模型
    #A)标准事件模型
    #Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll
    #B)高效事件模型
    #Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
    #Epoll:使用于Linux内核2.6版本及以后的系统。
    #/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
    #Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。
    use epoll;
    #单个进程最大连接数(最大连接数=连接数*进程数)
    #根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为。
    worker_connections 65535;
    #keepalive超时时间。
    keepalive_timeout 60;
    #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
    #分页大小可以用命令getconf PAGESIZE 取得。
    #[root@web001 ~]# getconf PAGESIZE
    #4096
    #但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。
    client_header_buffer_size 4k;
    #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=65535 inactive=60s;
    #这个是指多长时间检查一次缓存的有效信息。
    #语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.
    open_file_cache_valid 80s;
    #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
    #语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location  这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.
    open_file_cache_min_uses 1;
    
    #语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.
    open_file_cache_errors on;
}
 
 
 
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http
{
    #文件扩展名与文件类型映射表
    include mime.types;
    #默认文件类型
    default_type application/octet-stream;
    #默认编码
    #charset utf-8;
    #服务器名字的hash表大小
    #保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.
    server_names_hash_bucket_size 128;
    #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
    client_header_buffer_size 32k;
    #客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。
    large_client_header_buffers 4 64k;
    #设定通过nginx上传文件的大小
    client_max_body_size 8m;
    #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
    #sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
    sendfile on;
    #开启目录列表访问,合适下载服务器,默认关闭。
    autoindex on;
    #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
    tcp_nopush on;
     
    tcp_nodelay on;
    #长连接超时时间,单位是秒
    keepalive_timeout 120;
    #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    #gzip模块设置
    gzip on; #开启gzip压缩输出
    gzip_min_length 1k;    #最小压缩文件大小
    gzip_buffers 4 16k;    #压缩缓冲区
    gzip_http_version 1.0;    #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
    gzip_comp_level 2;    #压缩等级
    gzip_types text/plain application/x-javascript text/css application/xml;    #压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
    gzip_vary on;
    #开启限制IP连接数的时候需要使用
    #limit_zone crawler $binary_remote_addr 10m;
    #负载均衡配置
    upstream piao.jd.com {
     
        #upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
        server 192.168.80.121:80 weight=3;
        server 192.168.80.122:80 weight=2;
        server 192.168.80.123:80 weight=3;
        #nginx的upstream目前支持4种方式的分配
        #1、轮询(默认)
        #每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
        #2、weight
        #指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
        #例如:
        #upstream bakend {
        #    server 192.168.0.14 weight=10;
        #    server 192.168.0.15 weight=10;
        #}
        #2、ip_hash
        #每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
        #例如:
        #upstream bakend {
        #    ip_hash;
        #    server 192.168.0.14:88;
        #    server 192.168.0.15:80;
        #}
        #3、fair(第三方)
        #按后端服务器的响应时间来分配请求,响应时间短的优先分配。
        #upstream backend {
        #    server server1;
        #    server server2;
        #    fair;
        #}
        #4、url_hash(第三方)
        #按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
        #例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
        #upstream backend {
        #    server squid1:3128;
        #    server squid2:3128;
        #    hash $request_uri;
        #    hash_method crc32;
        #}
        #tips:
        #upstream bakend{#定义负载均衡设备的Ip及设备状态}{
        #    ip_hash;
        #    server 127.0.0.1:9090 down;
        #    server 127.0.0.1:8080 weight=2;
        #    server 127.0.0.1:6060;
        #    server 127.0.0.1:7070 backup;
        #}
        #在需要使用负载均衡的server中增加 proxy_pass http://bakend/;
        #每个设备的状态设置为:
        #1.down表示单前的server暂时不参与负载
        #2.weight为weight越大,负载的权重就越大。
        #3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误
        #4.fail_timeout:max_fails次失败后,暂停的时间。
        #5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
        #nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
        #client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug
        #client_body_temp_path设置记录文件的目录 可以设置最多3层目录
        #location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡
    }
     
     
     
    #虚拟主机的配置
    server
    {
        #监听端口
        listen 80;
        #域名可以有多个,用空格隔开
        server_name www.jd.com jd.com;
        index index.html index.htm index.php;
        root /data/www/jd;
        #对******进行负载均衡
        location ~ .*.(php|php5)?$
        {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
        }
         
        #图片缓存时间设置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 10d;
        }
         
        #JS和CSS缓存时间设置
        location ~ .*.(js|css)?$
        {
            expires 1h;
        }
         
        #日志格式设定
        #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
        #$remote_user:用来记录客户端用户名称;
        #$time_local: 用来记录访问时间与时区;
        #$request: 用来记录请求的url与http协议;
        #$status: 用来记录请求状态;成功是200,
        #$body_bytes_sent :记录发送给客户端文件主体内容大小;
        #$http_referer:用来记录从那个页面链接访问过来的;
        #$http_user_agent:记录客户浏览器的相关信息;
        #通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
        log_format access '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" $http_x_forwarded_for';
         
        #定义本虚拟主机的访问日志
        access_log  /usr/local/nginx/logs/host.access.log  main;
        access_log  /usr/local/nginx/logs/host.access.404.log  log404;
         
        #对 "/" 启用反向代理
        location / {
            proxy_pass http://127.0.0.1:88;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
             
            #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             
            #以下是一些反向代理的配置,可选。
            proxy_set_header Host $host;
            #允许客户端请求的最大单文件字节数
            client_max_body_size 10m;
            #缓冲区代理缓冲用户端请求的最大字节数,
            #如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
            #无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误
            client_body_buffer_size 128k;
            #表示使nginx阻止HTTP应答代码为400或者更高的应答。
            proxy_intercept_errors on;
            #后端服务器连接的超时时间_发起握手等候响应超时时间
            #nginx跟后端服务器连接超时时间(代理连接超时)
            proxy_connect_timeout 90;
            #后端服务器数据回传时间(代理发送超时)
            #后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
            proxy_send_timeout 90;
            #连接成功后,后端服务器响应时间(代理接收超时)
            #连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
            proxy_read_timeout 90;
            #设置代理服务器(nginx)保存用户头信息的缓冲区大小
            #设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
            proxy_buffer_size 4k;
            #proxy_buffers缓冲区,网页平均在32k以下的设置
            #设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
            proxy_buffers 4 32k;
            #高负荷下缓冲大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;
            #设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
            #设定缓存文件夹大小,大于这个值,将从upstream服务器传
            proxy_temp_file_write_size 64k;
        }
         
         
        #设定查看Nginx状态的地址
        location /NginxStatus {
            stub_status on;
            access_log on;
            auth_basic "NginxStatus";
            auth_basic_user_file confpasswd;
            #htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
        }
         
        #本地动静分离反向代理配置
        #所有jsp的页面均交由tomcat或resin处理
        location ~ .(jsp|jspx|do)?$ {
            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_pass http://127.0.0.1:8080;
        }
         
        #所有静态文件由nginx直接读取不经过tomcat或resin
        location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|
        pdf|xls|mp3|wma)$
        {
            expires 15d; 
        }
         
        location ~ .*.(js|css)?$
        {
            expires 1h;
        }
    }
}