Wave Spread...

Linux 运维手册之 NGINX 网页服务

分类:Linux 评论: 0

NGINX是一个免费的,开源的,高性能的HTTP服务器和反向代理,以及 IMAP / POP3 代理服务器。 NGINX 以其高性能,稳定性,丰富的功能集,简单的配置和低资源消耗而闻名。

----- 官方宣传语

虽然 NGINX 市场占有率并不占有绝对优势,但是对比其他WEB服务器还是有很大优势。

  1. 作为网页服务器:相比 ApacheNGINX 使用更少的资源,支持更多的并发连接(能够支持高达 50000 个并发连接数的响应),静态页面处理性能比 Apache3倍以上,但对动态内容支持较弱,需要其他依赖进行实现,并且组件不如 Apache 丰富。

  2. 作为负载均衡服务器:相比 PerlbalNGINX 既可以在内部直接支持 RailsPHP 程序对外进行服务, 也可以支持作为HTTP代理服务器对外进行服务。采用C语言进行编写,不论是系统资源开销还是CPU使用效率都要好很多。

其他优势

  1. NGINX 配置相对简洁,启动过程迅速,服务宕机可能性低,并且支持服务平滑升级。

  2. Apache是同步多进程模型,一个连接对应一个进程;NGINX是异步的,多个连接(万级别)对应一个进程。

  3. NGINX的优势是处理静态请求,CPU内存使用率低,Apache适合处理动态请求,所以一般前端用NGINX作为反向代理抗住压力,Apache作为后端处理动态请求。

NGINX 部署

NGINX 官方预编译版本支持以下发行版

RHEL/CentOS

版本 支持的平台
6.x x86_64, i386
7.4+ x86_64, ppc64le

Debian

版本 代号 支持的平台
8.x jessie x86_64, i386
9.x stretch x86_64, i386

Ubuntu

版本 代号 支持的平台
14.04 trusty x86_64, i386, aarch64/arm64
16.04 xenial x86_64, i386, ppc64el, aarch64/arm64
17.10 artful x86_64, i386
18.04 bionic x86_64

SLES

版本 支持的平台
12 x86_64

导入官方源

1). 为 RHELCentOS 设置 yum 仓库,例如编辑:

$ sudo vi /etc/yum.repos.d/nginx.repo

插入以下内容:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1

小贴士:需要将 "< OS >" 替换为系统发行版,将 "< OSRELEASE >" 替换为系统版本。

例如:在 CentOS 7 上可以使用

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

2). 为 DebianUbuntu 设置 apt 仓库,例如编辑:

$ sudo vi /etc/apt/sources.list.d/nginx.list

插入以下内容:

Debian 系统下

deb http://nginx.org/packages/debian/ codename nginx
deb-src http://nginx.org/packages/debian/ codename nginx

Ubuntu 系统下

deb http://nginx.org/packages/ubuntu/ codename nginx
deb-src http://nginx.org/packages/ubuntu/ codename nginx

小贴士:需要将 "< codename >" 替换为系统代号。

例如:在 Ubuntu 18.04 上可以使用

deb [arch=amd64] http://nginx.org/packages/ubuntu/ bionic nginx
deb-src [arch=amd64] http://nginx.org/packages/ubuntu/ bionic nginx

注意:因 Ubuntu 18.04 彻底移除了 x86 架构的支持,因此需要加入[arch=amd64]只检索 amd64 ,否则会有报错信息。

从仓库安装

配置仓库后即可使用官方的软件包管理命令安装官方仓库中的NGINX相应版本。

RHELCentOS 从官方仓库安装 NGINX

yum makecache
yum install nginx

DebianUbuntu 从官方仓库安装 NGINX

apt-get update
apt-get install nginx

软件包来源校验

RPM软件包和 DEB 存储库都使用数字签名来验证下载软件包的来源与完整性(是否被篡改)。
若想开启此功能,检查校验签名,则需要下载官方签名密钥并将其导入系统密钥池。

RHELCentOS 导入官方密钥:

$ sudo rpm --import nginx_signing.key

DebianUbuntu 导入官方密钥:

$ sudo apt-key add nginx_signing.key

注意:在 RHEL/CentOS 中默认不检查密钥,需要修改 /etc/yum.repos.d/nginx.repo 中的 gpgcheck=1 参数。

CentOS 7 中可以不下载密钥,直接在配置文件中指定:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgkey=http://nginx.org/keys/nginx_signing.key
gpgcheck=1
enabled=1

DebianUbuntu 中不导入密钥会报以下错误:

W: GPG error: http://nginx.org/packages/ubuntu bionic InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY ABF5BD827BD9BF62
E: The repository 'http://nginx.org/packages/ubuntu bionic InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

也可以使用以下命令导入密钥:

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62

注意:后面的密钥串ABF5BD827BD9BF62应替换为错误信息中的数值。

NGINX 模块

自动索引模块

ngx_http_autoindex_module

官方文档:点击跳转

配置模板:

location / {
    root html;
    autoindex on;
    autoindex_localtime on;
    autoindex_exact_size off;
}

语法:

autoindex on/off;
默认参数:off
字段位置:http, server, location

参数:

autoindex_exact_size off;    # 单位换算
# 可选参数:on | off ,默认 on 单位为 byte,off 换算为 kB,MB,GB

autoindex_localtime on;      # 时间格式
# 可选参数:on |off ,默认 off 显示的文件时间为GMT时间。on 显示的文件时间为文件的服务器时间。

charset utf-8,gbk;           # 字符集设置
# 可选参数:UTF-8 | GBK | GB2312 ,添加GBK后即可解决中文乱码

autoindex_format html;       # 网页格式
# 可选参数: html | xml | json | jsonp ,默认 html 。

状态监测模块

ngx_http_stub_status_module

官方文档:点击跳转

配置模板:

location = /basic_status {
    stub_status;
}

语法:

stub_status;
默认参数:  —
字段位置:server, location

访问限制模块

ngx_http_access_module

官方文档:点击跳转

配置模板:

location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
}

语法:

allow address | CIDR | unix: | all;
默认参数:  —
字段位置:http, server, location, limit_except

用户认证模块

ngx_http_auth_basic_module

官方文档:点击跳转

配置模板:

location / {
    auth_basic           "closed site";
    auth_basic_user_file conf/htpasswd;
}

语法:

auth_basic string | off;
默认:   off
auth_basic_user_file file;
字段位置:http, server, location, limit_except

注意:密码文件需严格按照以下格式进行生成。密码文件名可使用变量。

# comment
name1:password1
name2:password2:comment
name3:password3

生成密码可以使用阿帕奇工具包中的小工具

$ sudo yum install httpd-tools
$ sudo htpasswd -c /etc/nginx/auth_conf password

连接限制模块

ngx_http_limit_conn_module

官方文档:点击跳转

配置模板:

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    ...

    server {

        ...

        location /download/ {
            limit_conn addr 1;
        }

配置模板2:

http {
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    ...
    server {
        ...
        limit_conn perip 10;
        limit_conn perserver 100;
    }

语法:

limit_conn zone number;
默认: —
字段位置:http, server, location

日志:

limit_conn_log_level info | notice | warn | error;
默认:error;
字段位置:http, server, location

状态:

limit_conn_status code;
默认:503;
字段位置:http, server, location

请求限制模块

ngx_http_limit_req_module

官方文档:点击跳转

配置模板:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }

语法:

limit_req zone=name [burst=number] [nodelay];
默认: —
字段位置:http, server, location

示例用法:

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
    location /search/ {
        limit_req zone=one burst=5;
    }

说明:允许每秒平均不超过1个请求,并发不超过5个请求。

如果不希望在请求受限的情况下拒绝过多的请求,则应使用以下参数来推迟多余的请求:

limit_req zone=one burst=5 nodelay;

日志:

limit_req_log_level info | notice | warn | error;
默认: error;
字段位置:http, server, location

状态:

limit_req_status code;
默认: 503;
字段位置:http, server, location

日志记录模块

ngx_http_log_module

官方文档:点击跳转

NGINX 提供完备的日志记录功能,此模块可以深度定义日志格式,便于筛选可用信息。

配置模板:

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;

语法:

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
默认:
access_log logs/access.log combined;
字段位置:http, server, location, if in location, limit_except

日志变量详解:

$remote_addr, $http_x_forwarded_for # 记录客户端IP地址
$remote_user                        # 记录客户端用户名称
$request                            # 记录请求的URL和HTTP协议
$status                             # 记录请求状态
$body_bytes_sent                    # 发送给客户端的字节数,不包括响应头的大小
$bytes_sent                         # 发送给客户端的总字节数
$msec                               # 日志写入时间。 单位为秒, 精度是毫秒。
$http_referer                       # 记录从哪个页面链接访问过来的
$http_user_agent                    # 记录客户端浏览器相关信息
$request_length                     # 请求的长度(包括请求行, 请求头和请求正文)。
$request_time                       # 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始, 直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601                       # ISO8601标准格式下的本地时间。
$time_local                         # 通用日志格式下的本地时间。

日志缓存功能:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
默认:off;
字段位置:http, server, location

日志缓存参数标注:
max: 设置缓存中的最大文件描述符数量,如果缓存被占满,采用LRU算法将描述符关闭。
inactive: 设置存活时间,默认是10s
min_uses: 设置在inactive时间段内, 日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是1次
valid: 设置检查频率, 默认60s
off: 禁用缓存


NGINX 配置

此部分配置实质上是核心模块中内容(ngx_http_core_module),但是使用频率最高,因此单独拿出来进行分析。

监听端口(listen

示例配置:

server {
    listen       80;
    server_name  www.wavengine.com;
    root         /var/www/html/wavengine/blog;
    index        index.php index.html
    ...
}

注意:浏览器在访问页面时会默认访问 80 端口,因此网站的监听端口请勿修改(若做了端口转发或者负载均衡可使用其他端口),以防访客无法正常使用。

根目录(root

示例配置:

server {
    listen       80;
    server_name  www.wavengine.com;
    root         /var/www/html/wavengine/blog;
    index        index.php index.html
    ...
}

root 指定了此主机的根目录,所有资源会在此目录下寻找,因此请设置正确的根目录,部分产品解压后存在多个目录,请分辨实际的网站目录并指定。

补充:指定根目录后可以使用文件的相对地址来指定资源。

与之相关的还有一个 alias 作用与 root 相似,会将root目录重定向为alias 地址。

举个例子:

server {
        listen 80;
        index index.html;
        location /request_path/code/ {
                alias /local_path/code/;
        }
}

实际请求:/local_path/code/index.html

server {
        listen 80;
        index index.html;
        location /request_path/code/ {
                root /local_path/code/;
        }
}

实际请求:/local_path/code/request_path/code/index.html

索引页面(index

示例配置:

server {
    listen       80;
    server_name  www.wavengine.com;
    root         /var/www/html/wavengine/blog;
    index        index.php index.html
    ...
}

说明:指定索引页面后,NGINX 会按指定的顺序在根目录下搜索,显示为当前主机的主页。

虚拟主机 (VH

虚拟主机是指在一个 NGINX 配置文件中指定多个网站

$ cat /etc/nginx/conf.d/all.conf

配置文件模板

server {
    listen       80;
    server_name  blog.wavengine.com;
    root         /var/www/html/wavengine/blog;
    ...
}

server {
    ...
    listen       80;
    server_name  ftp.wavengine.com;
    root         /var/www/html/wavengine/ftp;
}

也可以将多个主机拆分为多个文件(文件名可以自定义,但必须以 .conf 结尾)

$ ll
-rw-r--r-- 1 root root 1.1K Apr 17 09:46 default.conf
-rw-r--r-- 1 root root  353 Aug 14 00:07 ftp.conf
-rw-r--r-- 1 root root 2.6K Aug 14 23:01 blog.conf
total 12K

小贴士:推荐在主配置文件上 /etc/nginx/nginx.conf 配置 http 段配置,在 /etc/nginx/conf.d/ 中配置 server 段配置。
不同的域名可以监听在同一个端口,请求会根据请求的域名进行自动分配,但是若同一域名绑定相同的地址会触发优先级问题(应尽量避免)。

资源定位(location

location 用于在一个主机中匹配用户访问的资源,并进行处理和回应。

匹配符 匹配规则 优先级
= 表示精确匹配 1
^~ 表示以某字符串开头 2
~ 表示区分大小写的正则匹配 3
~* 表示不区分大小写的正则匹配 4
!~ 表示区分大小写不匹配的正则 5
!~* 表示不区分大小写不匹配的正则 6
/ 通用匹配,任何请求都会匹配到 7

注意:~~* 正则匹配规则在匹配后会寻找更精准的location再次进行匹配。

文件检查(try_files

检查指定顺序的文件是否存在,并使用第一个找到的文件进行请求处理;处理在当前上下文中执行。根据rootalias指令从文件参数构造文件的路径。可以通过在名称的末尾指定斜杠来检查目录的存在,例如:$ URI /。如果未找到任何文件,则会进行内部重定向到最后一个参数中指定的uri

字段位置:server, location

示例配置:

server {
        listen      80;
        server_name test.wavengine.com;
        root        /test/code;
        index       index.html;
        location / {
                try_files $uri @java_page;
        }
        location @java_page {
                proxy_pass http://127.0.0.1:8080;
        }
}

说明:此配置文件使用后,若用户访问示例地址后会在 /test/code 下寻找 index.html 若不存在文件会将请求导向本地端口8080进行解析(Tomcat)。

NGINX 负载均衡

LBLoad Balance,负载均衡)是将一个任务分摊到多个操作单元上进行执行,从而分摊压力,增加吞吐量、加强数据处理能力、提高网络的灵活性和可用性。

NGINX 的负载均衡实质上是“反向代理”。

反向代理与负载均衡之间的关系:如果后端是一台服务器就叫反向代理,如果有多台就是负载均衡。反向代理才能实现负载均衡,负载均衡是做反向代理的目的之一。

“正向代理”和“反向代理”的区别:
简单地理解,正向代理隐藏用户身份,反向代理隐藏服务器身份。

正向代理与反向代理

举个例子:

  我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。

正向代理的用途:
(1)访问原来无法访问的资源。
(2)作为缓存,加速访问资源。
(3)对客户端访问授权,上网进行认证。
(4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息。

举个例子:

  我是一个用户,我访问某个网站,但是实质上给我提供数据的是另一个服务器,但是它隐藏在代理服务器后,我只能知道我连接的是谁,但是不知道具体谁给我提供的服务。隐藏了真实服务器的信息,提高了安全指数。

反向代理的用途:
(1)保证内网的安全,可以使用反向代理提供WAF功能,阻止web攻击。
(2)负载均衡,分摊压力,提高数据处理能力。

NGINX 反向代理配置

语法:

proxy_pass URL;
默认参数:—
字段位置:location, if in location, limit_except

跳转重定向

语法:

proxy_redirect default;
可选参数:proxy_redirect off;proxy_redirect redirect replacement;
默认参数:proxy_redirect default;
字段位置:http, server, location

头部设定

在默认使用反向代理时会遇到一个问题,抓包时可在头部信息中看到真实服务器地址及端口,这是不合理的,因此需要使用重新定义头部信息功能。

语法:

proxy_set_header field value;
默认参数:proxy_set_header Host $proxy_host;
            proxy_set_header Connection close;
字段位置:http, server, location

例子:

# 用户请求的时候HOST的值是www.wavengine.com, 那么代理服务会像后端传递请求的还是www.wavengine.com
proxy_set_header Host $http_host;
# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
# 客户端通过代理服务访问后端服务, 后端服务记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

其他参数:

# 代理服务连接后端服务器的连接超时时间,建议使用默认值
语法:proxy_connect_timeout time;
默认参数:proxy_connect_timeout 60s;
字段位置:http, server, location

# 代理服务等待后端服务器的响应时间
语法:proxy_read_timeout time;
默认参数:proxy_read_timeout 60s;
字段位置:http, server, location

# 后端服务器在规定时间之内必须传完所有的数据至代理
语法:proxy_send_timeout time;
默认参数:proxy_send_timeout 60s;
字段位置:http, server, location

代理缓冲区

代理缓冲功能开启的情况下,NGINX会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端。

语法:proxy_buffering on | off;
默认参数:proxy_buffering on;
字段位置:http, server, location

语法:proxy_buffer_size size;
默认参数:proxy_buffer_size 4k|8k;
字段位置:http, server, location

语法:proxy_buffers number size;
默认参数:proxy_buffers 8 4k|8k;
字段位置:http, server, location

配置优化

在同一个配置文件中全部定义这些参数会导致配置文件冗余复杂,可读性差。因此将这部分配置写入一个配置文件,然后统一调用。

比如:

[root@domain ~]# vim /etc/nginx/proxy_params

写入以下内容

proxy_redirect default;
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_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;

在其他配置文件中可以直接使用:

location / {
    proxy_pass http://127.0.0.1:8080;
    include proxy_params;
}

NGINX 负载均衡

负载均衡的作用是分摊压力,因此需要一台服务器暴露在外面用于分配工作,其他的服务器用于实际承担工作内容,因此需要定义一个“负载均衡池”,就是一个定义工作服务器的清单。这个清单在 NGINX 中称为 upstream

配置模板:

upstream backend {
    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;
    }
}

配置说明:定义了一个负载均衡池,其中有五台机器。weight 定义了权重,数值越大,分配使用的概率越大。backup 则是定义为备用机器,在其他机器可用的时候不会使用,只有当全部非备用机器宕机后才会实际使用。

upstream 中支持健康检查功能,可检测服务器的可用性,并对此进行实时调整。

配置模板:

resolver 10.0.0.1;

upstream dynamic {
    zone upstream_dynamic 64k;

    server backend1.example.com      weight=5;
    server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;
    server backend3.example.com      resolve;
    server backend4.example.com      service=http resolve;

    server backup1.example.com:8080  backup;
    server backup2.example.com:8080  backup;
}

server {
    location / {
        proxy_pass http://dynamic;
        health_check;
    }
}
参数 说明
down 不参与负载均衡
backup 预留的备份服务器
max_fails 允许请求失败的次数
fail_timeout 达到允许请求失败的次数后, 会在此时间内不参与负载均衡
max_conns 限制最大的接收连接数

负载均衡调度算法

方式 说明
轮询 按时间顺序逐一分配到不同的后端服务器(默认)
weight 加权轮询,值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的校验结果分配,来自同一IP的固定访问一个后端服务器(不推荐)
url_hash 按照访问URL的校验结果来分配请求,每个URL定向到同一个后端服务器(不推荐)
least_conn 最少连接数,哪个机器连接数少就分发新连接

NGINX 缓存

通常情况下缓存是用来减少后端压力,将压力尽可能的往前推,减少后端压力,提高网站并发延时。

通常在完善架构下会使用 MemcachedRedis 来优化缓存,提高缓存的 IO ,加快取用速率。

语法:

proxy_cache zone | off;
默认参数:proxy_cache off;
字段位置:http, server, location

缓存路径:

proxy_cache_path path [levels=levels]
[use_temp_path=on|off] keys_zone=name:size [inactive=time]
[max_size=size] [manager_files=number] [manager_sleep=time][manager_threshold=time]
[loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
默认参数:—
字段位置:http

缓存有效期:

proxy_cache_valid [code ...] time;
默认参数:—
字段位置:http, server, location

示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

缓存支持断点续传:

location /tmp-test/ {
                proxy_cache tmp-test;
                proxy_cache_valid  200 206 304 301 302 10d;
                proxy_cache_key $uri;
                proxy_set_header Range $http_range;
                proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/;
}

NGINX 实例

用反向代理方式实现动静分离实例

将用户的访问的请求分离,动态请求和静态请求剥离开,保证服务的可用性,即使某一种不可用也不影响另一种。

系统 部署服务 地址 节点
CentOS NGINX 192.168.69.112 N.1
CentOS NGINX 192.168.69.113 N.2
CentOS Tomcat 192.168.69.114 N.3

在节点 2 (192.168.69.113)操作:

新建配置文件:

[root@domain ~]# vim /etc/nginx/conf.d/access.conf 

写入以下内容:

server{
        listen 80;
        root /code;
        index index.html;

        location ~ .*\.(png|jpg|gif)$ {
                gzip on;
                root /soft/code/images;
        }
}

准备一个静态资源(png)

[root@domain ~]# wget -O /code/images/nginx.png http://nginx.org/nginx.png

在节点 3 (192.168.69.114)操作:

部署动态环境:

[root@domain ~]# wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.7/bin/apache-tomcat-9.0.7.tar.gz
[root@domain ~]# mkdir /opt/tomcat
[root@domain ~]# tar xf apache-tomcat-9.0.7.tar.gz -C /opt/tomcat/

编辑动态页面:

[root@domain ~]# vi /opt/tomcat/apache-tomcat-9.0.7/webapps/ROOT/java_test.jsp

写入以下内容:(注意不要使用vim

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<HTML>
    <HEAD>
        <TITLE>JSP Test Page</TITLE>
    </HEAD>
    <BODY>
      <%
        Random rand = new Random();
        out.println("<h1>Random number:</h1>");
        out.println(rand.nextInt(99)+100);
      %>
    </BODY>
</HTML>

在节点 1 (192.168.69.112)操作:

编辑配置文件:

[root@domain ~]# vim /etc/nginx/conf.d/proxy.conf 

写入以下内容:

upstream static {
        server 192.168.69.113:80;
}

upstream java {
        server 192.168.69.114:8080;
}

server {
        listen 80;
        server_name 192.168.69.112;

        location / {
                root /code;
                index index.html;
        }

        location ~ .*\.(png|jpg|gif)$ {
                proxy_pass http://static;
                include proxy_params;
        }

        location  ~ .*\.jsp$ {
                proxy_pass  http://java;
                include proxy_params;
        }

}

编辑网页文件:

[root@domain ~]# vim /code/index.html

写入以下内容:

<html lang="en">
<head>
        <meta charset="UTF-8" />
        <title>测试ajax和跨域访问</title>
        <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<script type="text/javascript">
$(document).ready(function(){
        $.ajax({
        type: "GET",
        url: "http://192.168.69.112/java_test.jsp",
        success: function(data) {
                $("#get_data").html(data)
        },
        error: function() {
                alert("fail!!,请刷新再试!");
        }
        });
});
</script>
        <body>
                <h1>测试动静分离</h1>
                <img src="http://192.168.69.112/nginx.png">
                <div id="get_data"></div>
        </body>
</html>

部署完成,现在访问

http://192.168.69.112/java_test.jsp
http://192.168.69.112/nginx.png
http://192.168.69.112/index.html

查看效果

通过识别 USER-AGENT 实现不同浏览器(设备)访问不同页面

示例配置:

http {
...
    upstream firefox {
        server 172.31.57.133:80;
    }
    upstream chrome {
        server 172.31.57.133:8080;
    }
    upstream iphone {
        server 172.31.57.134:8080;
    }
    upstream android {
        server 172.31.57.134:8081;
    }
    upstream default {
        server 172.31.57.134:80;
    }
...
}

server {
    listen       80;
    server_name  www.wavengine.com;

    location / {
        if ($http_user_agent ~* "Safari"){
        proxy_pass http://dynamic_pools;
        }     

        if ($http_user_agent ~* "Firefox"){
        proxy_pass http://static_pools;
        }

        if ($http_user_agent ~* "Chrome"){
        proxy_pass http://chrome;
        } 

        if ($http_user_agent ~* "iphone"){
        proxy_pass http://iphone;
        }

        if ($http_user_agent ~* "android"){
        proxy_pass http://and;
        }

        proxy_pass http://dynamic_pools;
        include proxy.conf;
        }
    }
}

访问不同路径使用不同服务器

方式一

使用负载资源池

upstream static_pools {
    server 10.0.0.9:80  weight=1;
}
upstream upload_pools {
    server 10.0.0.10:80  weight=1;
}
upstream default_pools {
    server 10.0.0.9:8080  weight=1;
}

server {
    listen       80;
    server_name  www.domain.com;

#url: http://www.domain.com/
    location / { 
        proxy_pass http://default_pools;
        include proxy.conf;
    }

#url: http://www.domain.com/static/
    location /static/ {
        proxy_pass http://static_pools;
        include proxy.conf;
    }

#url: http://www.domain.com/upload/
    location /upload/ {
        proxy_pass http://upload_pools;
        include proxy.conf;
    }
}

方式二

使用判断语句实现

if ($request_uri   ~*   "^/static/(.*)$")
{
        proxy_pass http://static_pools/$1;
}
if ($request_uri   ~*   "^/upload/(.*)$")
{
        proxy_pass http://upload_pools/$1;
}
location / { 
    proxy_pass http://default_pools;
    include proxy.conf;
}

NGINX 缓存

缓存过期周期
语法:

proxy_cache_valid [code ...] time;
默认参数: —
字段位置: http, server, location

配置模板:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404   1m;

缓存的维度
语法:

proxy_cache_key string;
默认参数:proxy_cache_key $scheme$proxy_host$request_uri;
字段位置:http, server, location

配置模板:

proxy_cache_key "$host$request_uri $cookie_user";
proxy_cache_key $scheme$proxy_host$uri$is_args$args;

举个例子
1. 环境准备

系统 角色 地址
CentOS Proxy 192.168.31.152
CentOS Web 192.168.31.153

2. 节点准备

建立网页 Demo

# mkdir -p /code/web{1..3}
# for i in {1..3};do echo Code1-Url$i > /code/web1/url$i.html;done
# for i in {1..3};do echo Code2-Url$i > /code/web2/url$i.html;done
# for i in {1..3};do echo Code3-Url$i > /code/web3/url$i.html;done

写入配置文件

# cat >/etc/nginx/conf.d/web_node.conf <'EOF'
server {
        listen 8081;
        root /code/web1;
        index index.html;
}
server {
        listen 8082;
        root /code/web2;
        index index.html;
}
server {
        listen 8083;
        root /code/web3;
        index index.html;
}
EOF

重启服务

# systemctl restart nginx

检查服务

# ss -lnt | grep 80
State       Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN      0      100         0.0.0.0:8081                          *:*                  
LISTEN      0      100         0.0.0.0:8082                          *:*
LISTEN      0      100         0.0.0.0:8083                          *:*

配置缓存

# mkdir /code/cache
# vim /etc/nginx/conf.d/proxy_cache.conf

写入如下配置

upstream cache {
    server 192.168.31.153:8081;
    server 192.168.31.153:8082;
    server 192.168.31.153:8083;
}
proxy_cache_path /soft/cache levels=1:2 keys_zone=code_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
        listen 80;
        server_name 192.168.31.152;
        location / {
                proxy_pass http://cache;
                proxy_cache code_cache;
                proxy_cache_valid 200 304 12h;
                proxy_cache_valid any 10m;
                add_header Nginx-Cache "$upstream_cache_status";
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503  http_504;
                include proxy_params;
        }
}

注释:
proxy_cache 存放缓存临时文件
levels 按照两层目录分级
keys_zone 开辟空间名, 10m:开辟空间大小, 1m可存放8000key
max_size 控制最大大小, 超过后Nginx会启用淘汰规则
inactive 一小时没有被访问缓存会被清理
use_temp_path 临时文件, 会影响性能, 建议关闭
proxy_cache 开启缓存
proxy_cache_valid 状态码200|304的过期为12h, 其余状态码10分钟过期
proxy_cache_key 缓存key
add_header 增加头信息, 观察客户端respoce是否命中
proxy_next_upstream 出现502-504或错误, 会跳过此台服务器访问下台

缓存测试

[root@domain ~]# curl -s -I http://192.168.31.152/url3.html | grep "Nginx-Cache"
Nginx-Cache: MISS

[root@domain ~]# curl -s -I http://192.168.31.152/url3.html | grep "Nginx-Cache"
Nginx-Cache: HIT

缓存清理

  1. 可直接删除缓存目录
  2. 可以使用 ngx_cache_purge 模块(需重新编译)

指定页面不缓存
在 server 字段中添加即可。

upstream cache {
    server 192.168.31.153:8081;
    server 192.168.31.153:8082;
    server 192.168.31.153:8083;
}
proxy_cache_path /soft/cache levels=1:2 keys_zone=code_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
        listen 80;
        server_name 192.168.31.152;
        if ($request_uri ~ ^/(url3|login|register|password)) { # 新增内容
                set $cookie_nocache 1;
        }
        location / {
                proxy_pass http://cache;
                proxy_no_cache $cookie_nocache $arg_nocache $arg_comment; # 新增内容
                proxy_no_cache $http_pargma $http_authorization; # 新增内容
                proxy_cache code_cache;
                proxy_cache_valid 200 304 12h;
                proxy_cache_valid any 10m;
                add_header Nginx-Cache "$upstream_cache_status";
                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503  http_504;
                include proxy_params;
        }
}

缓存日志
修改默认日志格式

[root@domain pinghsu]# cat /etc/nginx/nginx.conf 
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$http_user_agent' '$request_uri' '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"' '"$upstream_cache_status"';

参考链接

回复