nginx基本应用(二)

影子

我总是惊讶地发现,我不假思索地上路,因为出发的感觉太好了。世界突然充满了可能性。
杰克 凯鲁亚克

反向代理

正向代理与反向代理

正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从原始服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转交并且将获得的内容返回给客户端。
反向代理实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
反向代理工作在服务期的前端,作为前端服务器,正向代理工作在客户端的前端,为客户端做代理。

反向代理的作用

  1. 保证内网的安全,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网。

  2. 可以通过反向代理来实现负载均衡,通过反向代理服务器来优化网站的负载

反向代理示例

环境

192.168.0.168  代理服务器(nginx)
192.168.0.52   后端服务器(httpd)

修改nginx代理配置

location /wanger {
            proxy_pass http://192.168.0.52;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

添加后端192.168.0.52/wanger首页

mkdir /var/www/html/wanger
echo 192.168.0.52 > /var/www/html/wanger/index.html

在前端服务器进行访问测试

当客户端访问192.168.0.168/wanger/时,会将请求转发给后端192.168.0.52/wanger/index.html

[root@192.168.0.168]# curl 127.0.0.1/wanger/
192.168.0.52

可以看到反向代理测试成功

proxy_set_header指令解释

proxy_set_header指令设置nginx发送到后端服务器的标头
上述配置中,将请求标头的Host字段设置为$ host变量。
将X-Real-IP字段设置proxy_add_x_forwarded_for变量,$proxy_add_x_forwarded_for是ngx_http_proxy_module内置变量

proxy_add_x_forwarded_for变量

proxy_add_x_forwarded_for变量包含了X-Forward-For字段和remote_addr变量,并用逗号分隔,当X-Forwarded-For字段不存在时,那么$proxy_add_x_forwarded_for变量等于$remote_addr变量,当一个web应用被两台nginx代理服务器转发的时候,第一台的nginx代理的X-Forwarded-For字段为真实的客户端ip,第二台nginx代理的X-Forwarded-For字段为客户端ip,第一台代理的ip地址,也就是说,只有当代理服务器的数量大于1的时候,proxy_add_x_forwarded_for才有效果

图片

修改后端web日志格式

首先查看访问后端的日志,可以看到访问ip显示的还是nginx代理的ip

图片

修改httpd日志格式,将日志中的ip修改为客户端ip

vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Real-IP}i %{Host}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

修改后的日志格式如下:

图片

这样就会在后端服务器中显示真实的客户端ip了

proxy_pass加不加/的区别

当proxy_pass在后面的url加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走

示例

location /wanger {
            proxy_pass http://192.168.0.52;
        }

此时后端的url为192.168.0.52/wanger/index.html

location /wanger {
            proxy_pass http://192.168.0.52;
        }

此时后端的url为192.168.0.52/index.html

负载均衡

负载均衡可以将请求前端的请求分担到后端多个节点上,提升系统的响应和处理能力。

环境

192.168.0.168   负载均衡服务器
192.168.0.52  上游节点1
192.168.0.84   上游节点2

负载均衡调度策略

weight轮询(默认)

将请求按时间顺序分配到后端服务器,通过weight可以定义轮询权重,权重越高,访问几率越高

upstream read{
        server 192.168.0.52 weight=2 max_fails=3 fail_timeout=20s;
        server 192.168.0.84:8080 weight=1 max_fails=3 fail_timeout=20s;
        server 192.168.0.96 down;
        server 192.168.0.168  backup;
}
  1. max_fails,允许fail_timeout时间内请求失败的最大次数,否则后端服务器将被标记为不可用

  2. fail_timeout,表示错误次数的超时时间;

    当被标记为不可用后,暂停服务的时间。

  3. down,将当前的server标记为不可用,即不参与负载均衡。

  4. backup,标记为备用服务器,当所有非backup服务器不可用或者忙时,会请求该服务器。

请求结果如下:

图片

ip_hash

将请求按照访问ip的hash结果分配到后端服务器,这样同一ip每次请求都能够访问到同一台后端服务器,可以解决动态网页的session问题

upstream read{
        ip_hash
        server 192.168.0.52;
        server 192.168.0.84:8080;
}

请求结果如下:

图片

最少连接(least_conn)

根据后端服务器当前的连接情况,将请求分配给当前连接数最少的一台后端服务器上

upstream read{
        least_conn;
        server 192.168.0.52;
        server 192.168.0.84:8080;
}

请求结果如下:

图片

fair

将请求分配给响应时间短的后端服务器

upstream read{
        fair;
        server 192.168.0.52;
        server 192.168.0.84:8080;
}

url_hash

根据访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率

upstream read{
        hash $request_uri;
        server 192.168.0.52;
        server 192.168.0.84:8080;
}

动静分离

为什么要做动静分离

Nginx的静态处理能力很强,但是动态处理能力不足,动静分离之后,方便对静态资源做缓存操作,并且提高了网站的响应速度

动静分离配置

upstream static{
        server 192.168.0.52 weight=2 max_fails=3 fail_timeout=20s;     
}
upstream dynamic{
        server 192.168.0.168:9200  weight=2 max_fails=3 fail_timeout=20s;
}
server {
     listen 80;
     server_name localhost;
    location ~* \.php$ {              
                fastcgi_pass http://dynamic;
                fastcgi_index index.php;  
                fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
                include fastcgi_params;
        }
    location ~* \.(jpg|gif|png|css|html|htm|js)$ {  
                proxy_pass http://static; 
                expires 12h;   
}

nginx代理缓存

nginx的ngx_http_proxy_module自带了缓存功能,下面介绍几个常用的指令以及如何配置。

proxy_cache_path

nginx缓存的内容是放在磁盘中的,所以我们需要定义存放缓存的载体,proxy_cache_path设置缓存的路径和其他参数。缓存中的文件名为proxy_cache_key定义的字符串的hash结果

proxy_cache_path语法

语法 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

参数解释:

  • path:

    定义缓存文件的路径,目录不存在会自动创建

  • levels:

    定义缓存目录的级别,最多为3级,每级目录名长度字符只能为1或者2个字节。

  • use_temp_path:

    当参数为on时,会使用proxy_temp_path定义的目录,否则临时文件将直接放在缓存目录里

  • keys_zone:

    定义共享内存名字和共享内存大小,name表示共享内存名称,size表示共享内存大小

  • inactive:

    在inactive参数指定的时间内未被访问的缓存数据 将从缓存中删除,默认为十分钟

  • max_size:

    定义缓存文件最大空间,超过将会被cache manager进程删除掉最近最少使用的缓存

  • manager_files:

    定义cache manager进程执行一次所要删除的文件数,默认为100

  • manager_sleep:

    执行一次cache manager进程后的休眠时间,默认为50毫秒

  • manager_threshold:

    执行一次cache manager删除循环的最大耗时,默认为200毫秒。

  • loader_files:

    cache loader进程用于将磁盘中原有的缓存数据加载到共享内存中,也是通过循环来完成的,用于定义每次载入的最大文件数,默认为100

  • loader_sleep:

    执行一次载入缓存进程的休眠时间,默认为50毫秒

  • loader_threshold:

    执行一次载入缓存进程所需的时间,默认为50毫秒

proxy_cache

用来指定使用哪个共享内存,使用proxy_cache_path中的name来引用

proxy_cache语法

语法 proxy_cache zone 丨 off;
默认 proxy_cache off;
应用位置 http,server,location

proxy_cache_key

定义缓存的key,将以key的hash值作为缓存文件名

proxy_cache_key语法

语法 proxy_cache_key string;
默认 proxy_cache_key $ scheme $ proxy_host $ request_uri;
应用位置 http,server,location

proxy_cache_valid

用于设置不同响应代码的缓存时间

proxy_cache_valid语法

语法 proxy_cache_valid [code …] time;
默认 -
应用位置 http,server,location
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_valid 5m;
proxy_cache_valid any 1m;

以上代码表示状态码为200和302的缓存有效期为10分钟,状态码为404的缓存有效期为1分钟,如果不指定状态码,那么只有缓存状态码200,301和302各五分钟,any表示缓存任何响应

在响应头中设置缓存时长

  • 当X-Accel-Expires为0时,禁止缓存内容,使用@可以设置一天中的某一时刻

  • 当请求头中包含“Set-Cookie”字段时,则不会缓存此类响应

  • 当”Vary”字段的值为”*”时,则不会缓存此类响应

proxy_no_cache

定义不将响应保存到缓存的条件。当字符串参数为真时,则响应不会保存到缓存

proxy_no_cache语法

语法 proxy_no_cache string …;
默认 -
应用位置 http,server,location

proxy_cache_bypass

定义不从缓存中获取响应的条件,当字符串参数为真时,则不会从缓存中获取响应

proxy_cache_bypass语法

语法 proxy_cache_bypass string …;
默认 -
应用位置 http,server,location

$upstream_cache_status变量

$upstream_cache_status是一个位于ngx_http_upstream_module模块来显示缓存状态的变量,可以在配置中添加一个http头来显示此变量的值

变量的值

  • MISS:

    未命中的缓存

  • HIT:

    命中缓存

  • EXPIRED:

    缓存已经过期,请求将被传递到后端

  • STALE:

    后端将得到过期的应答

  • UPDATING:

    正在更新缓存,将使用旧的应答

  • REVALIDATED:

    nginx验证了旧的缓存依然有效

  • BYPASS:

    缓存被绕过了,应答是从原始服务器获得的

代理缓存配置示例

为验证缓存,这里我将缓存超时时间设为1分钟

proxy_cache_path /data/cache levels=1:2 keys_zone=cache:10m max_size=100m inactive=1m use_temp_path=off;
    server {
        listen       80;
        server_name  wanger.com;
        include /etc/nginx/default.d/*.conf;
        location /wanger {
            proxy_pass http://192.168.0.52;
            proxy_cache cache;
            proxy_cache_valid 200 301 1m;
            add_header X-Cache $upstream_cache_status;
            proxy_cache_key $host$uri;
        }
   }

可以看到第一次访问并没有命中缓存,而第二次访问的时候已经建立好缓存了

图片

查看缓存目录,可以看到缓存文件已经存在,并且前两级的目录名是缓存文件名的后三个字符

图片

进入后端服务器,添加响应头字段X-Accel-Expires,并将值设置为3

server {
        listen       80;
        server_name  localhost;
        add_header X-Accel-Expires 3;
location / {
                root    html;
                index   index.html;
        }
    }

再次进行测试,可以看到第一次请求显示缓存已经过期

图片

再次进入后端服务器,添加响应头字段Vary,并将其值设置为”*”,并进行测试

server {
        listen       80;
        server_name  localhost;
        add_header X-Accel-Expires 3;
        add_header Vary *;
location / {
                root    html;
                index   index.html;
        }
    }

可以看到index.htm文件一直没有被缓存

图片

代理缓存清理

nginx提供了一个第三方模块ngx_cache_purge,GitHub地址:https://github.com/FRiCKLE/ngx_cache_purge
安装ngx_cache_purge模块需要重新编译nginx,并使用—add-module=模块位置参数添加模块到nginx里

proxy_cache_purge语法

这里需要用到proxy_cache_purge指令

语法 proxy_cache_purge zone_name key
默认 -
应用位置 location

配置示例

location ~ /purge(/.*) {    proxy_cache_purge cache $host$1;}location /wanger {    proxy_pass http://192.168.0.52;    proxy_cache cache;    proxy_cache_valid 200 301 1m;    add_header X-Cache $upstream_cache_status;    proxy_cache_key $host$uri;}

代理缓存清理测试

由于我缓存过期时间设置的是1分钟,当我命中缓存之后,就开始进行缓存清理测试,之后在一分钟内再次访问同一个URL,就发现缓存命中失败了

图片

gzip压缩

gzip压缩模块提供了压缩文件内容的功能,通过压缩可以使服务器与浏览器之间传输的数据量更小,提高了客户端的响应速度,但压缩也会消耗nginx性能

指令解释

  • gzip on|off:

    是否开启gzip,默认为off

  • gzip_buffers number size:

    number指服务器向系统申请缓存空间的个数,size指每个缓存空间的大小

  • gzip_comp_level [1-9]:

    设置压缩级别,默认为1(级别越高,压的越小,越浪费CPU计算资源)

  • gzip_disable regex:

    使用正则匹配某种浏览器类型不进行压缩

  • gzip_min_length length:

    设置将被压缩的响应的最小长度,默认为20

  • gzip_types text/plain application/xml:

    对哪些类型的文件启用压缩,文件类型可以在nginx/mime.types文件里查看

  • gzip_vary on|off:

    启用或禁用插入“Vary:

    Accept-Encoding”响应头字段

配置示例

server {
        listen       80;
        server_name  192.168.0.168;  
        gzip        on;
        gzip_types  image/jpeg;
        gzip_buffers 32 4K;
        gzip_min_length 100;
        gzip_comp_level 6;
        gzip_vary on;
}

测试压缩配置

浏览器要禁用浏览器缓存,可以看到压缩之后图片大小是75.9KB,响应头中也会多一个字段Content-Encoding: gzip

图片

将gzip参数修改为off,重载nginx,再来看图片大小为76.4KB

图片


欢迎各位一起交流,提出建议

图片

------本页内容已结束,喜欢请分享------

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享