+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

张贺,多年互联网行业工作经验,担任过网络工程师、系统集成工程师、LINUX系统运维工程师

个人网站:www.zhanghehe.cn

笔者微信:zhanghe15069028807,现居济南历下区

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-


nginx缓存

基本概念

为什么反向代理最好要有缓存功能

如果前端nginx代理没有缓存的话,那么对于用户的每一个请求,nginx代理都要向后端real-serever再发起一次请求,等到real-serever响应回复报文之后,nginx代理再回复给客户端。当有缓存功能之后,对于经常访问的页面(比如电商网站的首页),nginx代理不用老是去real-serever去拿,而是本地缓存一份,用户再来访问的时候,nginx前端代理直接回复给客户端,会大大的提升用户访问网站的速度。

LVS、nginx、varnish缓存的对比

LVS没有缓存功能,100个用户先后访问同一个网页,LVS也要向后端转发100次。

nginx最出名的是其并发响应的高性能,对于反向代理来说非常的优秀,但是nginx的缓存功能上不如varnish。

varnish和nginx都有反向代理和缓存的功能,varnish更加侧重于缓存。

我们可以将nginx代理和varnish组合起来使用,使用其长处,但每加一级设备报文的速度也就慢了,有没有更好的办法?有,那就是将varnish和nginx安装到同一个系统当中,让它们使用本地进程间通信的方式交互。

所有的信息都能缓存吗

GET、HEAD、PUT、POST,DELETE这五种方法当中,我们没有必要缓存PUT、POST、DELETE方法携带的内容,因为用户通常用这种方法所做的事情都是“一锤子"买卖,假如用户通过PUT提交一些信息,别的用户是不太可能与这个用户提交相同的内容,缓存了也没有什么用。

还有用户私有信息,比如cookie,cookie信息也不能缓存,因为每一个用户的cookie也是不一样的。

缓存什么内容由谁决定

缓存什么内容当然是我们说了算,我们要告诉nginx代理能缓存什么,不能缓存什么。客户端也可以决定不使用nginx代理当中缓存的内容,比如浏览器的shift+F5强刷就表示不使用代理缓存中的内容,而去后端取最新的数据。web集群在可以通过在报文上加上一些缓存控制字段,告诉nginx代理哪些内容可以缓存,哪些内容不可以缓存。

缓存生成的过程

缓存当中缓存的内容是用户经常访问的内容,是经过某种算法算出来的,这些内容并不会凭空而来,而是有一定的访问数据量之后才逐渐生成的,所以缓存上线后对速度的提升不是立竿见影的,而是要等一段时间,当缓存里面缓存了一定的内容之后速度才会明显提升。当然,我们为了让缓存上线就可以使用,可以在上线之间使用压力测试让缓存里面存放一些数据再上线,虽然压力测试所访问的页面可能与真实用户访问的页面有一些出入,但是缓存当中有数据总比没有数据要强吧!做完比做好更重要,更何况,缓存算法会一直生效,会踢出不经常访问的页面,保留命中率最高的页面。

我们拿URI缓存来举例子,假设我们在nginx代理上启用了缓存功能,并告诉nginx代理通过uri进行缓存,当用户访问www.zhanghehe.com.cn的时候,代理第一次肯定是去后端找web集群去拿数据,把数据响应给用户,然后会将www.zhanghehe.com.cn做一次HASH,生成一串字符,从左向右或从右向左取一位、二位、或三位十六进制数据,生成缓存目录,假如在一级目录上取一位的话,一位表示16个目录(4个比特),在二级目录取取二位(8个比特)的话,就表示生成255个子目录,同理还可以再有三级目录,最后将www.zhanghehe.com.cn的响应内容就缓存到最后一级目录下面。

注意,缓存内容是保存在硬盘当中的,但是nginx代理生成的的HASH表会一直保存在内存当中,优先级和速度都是最高的,就像我们在做数据库的索引似的,查第100万条数据与查第一条数据消耗的时间几乎是一样的。

缓存命中的过程

我们先不谈缓存的命中过程,我们先来谈一下在文件系统中cat /etc/passwd的步骤,bash程序会通过系统变量找到cat命令代码交给内核执行,然后内核会去硬盘上找/etc/passwd这个文件,怎么找的呢?先要找到根对应的inode号才能找到根的元数据,找到元数据之后才能知道根里面的内容存放到哪些数据块上了,找到了根的数据块,还要从这些数据块当中找到etc目录对应的inode块的地址,再找到etc对应的inote块,然后找到etc目录对应的内容,再找到passwd文件对应的inode号,最后才找到内容。我们发现内核找一个文件真的好麻烦,需要一级一级的找。

缓存命中的过程不是这个样子的,不需要一级一级的找,尽管缓存的内容也会存放在文件系统的二级或三级目录下,但是不需要这样一层一层的找,我们上面说过,生成缓存之后内存里面会有一个HASH表,HASH表是以键值对的方式对数据进行存储的,键是URI哈希之后的内容,而后面的值就是URI对应的块地址,当用户的请求的URi进入到nginx反向代理的时候,首先要哈希URI,然后通过哈希得到的值与哈希表核对,看内存中哈希表是否有缓存的内容,如果有的话直接通过键值的方式去硬盘的数据块当中取出内容,不用经过文件系统查找那一套逐级查看,而是通过哈希表一步到位!

nginx代理缓存关机之后,hash表丢失,开机后会自动根据硬盘中的内容自动生成。

常用模块

proxy_cache

proxy_cache_path:定义缓存的内容存到哪个路径下;Context: http

proxy_cache zone | off; 在缓存起一个名字,方便调用;Context: http, server, location

proxy_cache_key string; 指明要通过什么进行缓存,缓存中用于“键”的内容,下面这是默认值

默认值:proxy_cache_key $scheme$proxy_host$request_uri;

proxy_cache_valid [code ...] time;定义对特定响应码的响应内容的缓存时长;定义在http{...}中;

proxy_cache_use_stale ;后端服务器宕机了,代理是否可以通过缓存的内容来响应,可以在这里定义一个502,假如后端主机返回了502,我们这里可以通过缓存的内容对客户端响应。

proxy_cache_methods GET | HEAD | POST ...;,响应哪些方法,默认仅是GET和HEAD。

第一步:定义缓存

//http段下定义
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g inactive=20m;

缓存内容存放在/var/cache/nginx/proxy_cache,目录分为三级结构,每一级目录16个子目录(不会一次性生成),内存中的缓存键的区域名字是pxycache,大小开辟20m的空间,磁盘空间用1g,默认非活动时间(多长时间没有被命中)是10分钟,如果10分钟内某个缓存条目没有被命中就会被清理出去,我们这里定义成20分钟。

第二步:调用缓存

//定义需要调用缓存功能的配置段,例如server{...};
proxy_cache pxycache; #调用缓存,pxycache是第一下定义过的。
proxy_cache_key $request_uri; #根据uri缓存
proxy_cache_valid 200 302 301 10m; #对于后端返回200,302,301状态码的界面缓存10分钟
proxy_cache_valid 404 1m; #404状态码缓存1分钟
proxy_cache_use_stale http_502;
proxy_cache_methods GET HEAD;

//效果查看,果然是三级目录,缓存了两个内容,我们可以查看一下。
[root@nginx_proxy ~]# tree /var/cache/nginx/proxy_cache/
/var/cache/nginx/proxy_cache/
└── 9
└── d
├── 7
│   └── 6666cd76f96956469e7be39d750cc7d9
└── 9
└── 35a63c8a85b1279a0f991ce8828fb9d9
//查看都缓存了什么内容
cat 6666cd76f96956469e7be39d750cc7d9 .
§X^mW^¼¤X^ՒҹX>
"5e571e6d-e"
KEY: /
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Fri, 28 Feb 2020 05:27:25 GMT
Content-Type: text/html
Content-Length: 14
Last-Modified: Thu, 27 Feb 2020 01:42:05 GMT
Connection: close
ETag: "5e571e6d-e"
Accept-Ranges: bytes this is 80.11 #整个网页里面的所有内容都缓存了
cat: .: Is a directory

超时相关

这里超时相关指的是向后请求或向后发送的连接或报文超时,后就是web集群,如果想定义从nginx代理向客户端的就得通过nginx的一些相关超时模块keepalive等。

proxy_connect_timeout time; 三次握手的超时时间,默认为60s;最长为75s;

proxy_read_timeout time; 请求的超时时间,默认为60s;最长为75s;

proxy_send_timeout time; 发送超时时长,默认为60s;最长为75s;

为什么会超时呢?超时的原因很简单,比如主机突然宕机了,三次握手会中断,代理向后发送的请求报文,或者发送的报文都可能会超时,再次强调,我们这里的超时时间指提nginx代理到web集群这一段的超时时间,而不是面向客户端的一侧,想要定义面向客户端一侧的超时时间也很简单,在nginx代理上通过nginx_http一些模块定义即可,我在nginx那一篇博客当中有详细阐述,这里不过多阐述。

//示例
server {
listen 80;
server_name www.zhanghehe.com.cn; proxy_cache pxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale http_502;
proxy_cache_methods GET HEAD;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s; location / {
proxy_pass http://192.168.80.11:80;
} location /admin {
proxy_pass http://192.168.80.11;
} location /images {
proxy_pass http://192.168.80.11/images/;
}
}

常见架构

第一种架构当中,静态页面nginx代理自己就处理了,动态页面使用php-fpm来处理,但php-fpm处理动态并发请求的能力太差了,所以又有第二种架构,让apache和php结合在一起,前端nginx代理通过http协议传递给apche,然后apache和php使用本地进程间的通信方式,大大提高了并发请求。

第三种架构更好一些,nginx代理专心处理代理和缓存,静态内容也不管了,分发给一台专门的服务器。

前三种架构在数据库方面没有做优化,实际是数据库是最慢的一环,我们可以在apache+php下旁挂一个memcache,memcache的性能没的说,内存级缓存,每秒几十万的处理量,而数据库每秒不到一百个,性能大大提高,但因其支持的数据类型较少,所以慢慢被redis代替,redis支持的数据类型更多,而且硬盘也能做存储,内存当中的数据不会丢失。

nginx反向代理(2)的更多相关文章

  1. 使用python自动生成docker nginx反向代理配置

    由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...

  2. Nginx反向代理,负载均衡,redis session共享,keepalived高可用

    相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...

  3. Nginx反向代理部署指南

    一.反向代理 我们都知道,80端口是web服务的默认端口,其他主机访问web服务器也是默认和80端口进行web交互,而一台服务器也只有一个80端口,这是约定俗成的标准. 我们来看下面两个场景: 1.服 ...

  4. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...

  5. Nginx反向代理和负载均衡

    一.Nginx反向代理设置 从80端口转向其他端口反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的 ...

  6. nginx 反向代理

    nginx 反向代理 vim nginx.conf http { ..... upstream "tomcatweb" { server 172.30.13.199:8080; s ...

  7. 关于nginx反向代理后获取不到客户端的真实ip地址问题

    前段时间在我的网站上用nginx做了一下反向代理,最近发现不能获取客户端ip了,都是拿到的127.0.0.1的本地ip... 通过查资料后,再去看了看我的配置文件,结果发现我没有如下配置: nginx ...

  8. Nginx反向代理配置可跨域

    由于业务需要,同一项目中的前端代码放在静态环境中,而后端代码放在tomcat中,但此时问题却出现了:前端使用ajax请求后端获取数据时出现如下报错 XMLHttpRequest cannot load ...

  9. Nginx反向代理搭建配置

    1.反向代理方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将服务器上得到的结果返回给internet 上请求连接的客户端,此时代理服务器对外就表现为一个 ...

  10. nginx反向代理docker registry报”blob upload unknown"解决办法

    问题症状:keepalived+nginx反向代理后端docker registry群集时,使用docker客户机向registry push镜像时出现 "blob upload unkno ...

随机推荐

  1. 【前端之BOM和DOM】

    " 目录 #. window对象介绍 #. window子对象 1. 浏览器对象 navigator 2. 屏幕对象 screen 3. 历史 history 4. 地址(URL)  loc ...

  2. centos7.5下安装jenkins

    最近从头搭建了一套python+selenium+pytest+allure+Jenkins的环境,虽然网上挺多的,不过还是记录下来,毕竟坑还是挺多的....... 先从搭建jenkins开始把! 方 ...

  3. P1217

    最快的办法就是打表了...不然怎么都会TLE. 先计算出给定最大范围内的所有回文质数: #include <bits/stdc++.h> using namespace std; #def ...

  4. phpRedis函数使用总结【分类详细】

    <?php /*1.Connection*/ $redis = new Redis(); $redis->connect('127.0.0.1',6379,1);//短链接,本地host, ...

  5. 03-Docker-Engine详解

    目录 03-Docker-Engine详解 摆脱 LXC 摒弃大而全的 Docker daemon 开放容器计划(OCI)的影响 runc containerd 启动一个新的容器 该模型的显著优势 s ...

  6. docker-install-v0.1-alpha

    Written by Zak Zhu docker-install-v0.1-alpha/ ├── inventory ├── roles │ └── docker │ ├── defaults │

  7. nginx-cache

    test.conf proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m; server { listen 80; server_name ...

  8. Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析

    目录 0.前言 1.TemporalAccessor源码 2.Temporal源码 3.TemporalAdjuster源码 4.ChronoLocalDate源码 5.LocalDate源码 6.总 ...

  9. 关于ASA的TCP MSS

    About the TCP MSS The TCP maximum segment size (MSS) is the size of the TCP payload before any TCP a ...

  10. JavaScript - call() , apply() and bind()

    参考 https://www.codementor.io/niladrisekhardutta/how-to-call-apply-and-bind-in-javascript-8i1jca6jp h ...