引言
随着一阵阵秋风吹过和一场场秋雨降临,天气早以由热转凉。在这准备步入严寒之际。起早的吒吒辉辉紧紧裹了下被子,鼻子依旧竖立着大鼻涕在那键盘上啪啪啪敲打着。想必大家此刻依旧在清晨甜美的梦乡之中,此刻唯独我眼角默默的流出了眼泪,只差泣不成声
都是心酸,都是泪,好了 好了 别被,小吒带篇了,走着,走着
![4ddacae1661dcbb25998b5465325cad5.png](https://i-blog.csdnimg.cn/blog_migrate/6edd47bf75b3a6c9371cb6c974fc59d9.jpeg)
开篇
继上篇后,咱们分布式多级缓存的链路,将会驶入网络缓存阶段,如果没看到上文的同学请返回阅读。
小白:老吒,网络不都是做请求--响应数据吗?那里有缓存?这缓存是干啥得?我 TM 要这缓存有啥用
吒吒辉:其实不然,可能你使用到了,但对网络缓存不明确,它满足什么条件?实现原理是什么?什么场景使用? 架构里面的代表是什么?这些都是得作为我暖男的必要条件,必须得给大家安排 (#^.^#)
![4457dca4c183902f7953a4465a76922d.png](https://i-blog.csdnimg.cn/blog_migrate/306d354b60f1d3a194b08143255a6cbb.png)
什么是网络缓存?
故名思议,就在请求--响应阶段,通过使用缓存来提高请求响应的速度,毕竟只有通信才会涉及到网络数据的传输。
可能有小伙伴会觉得,网络缓存难道是在网络上面的缓存?其实不然,看吒吒辉的
试想一个完整HTTP请求。它采用报文的方式发送数据,根据TCP协议来进行数据的传输。这个网络上面有缓存吗?
那都是通过电信号把咱们数据通过网络传输过去(这是抽象,实体就时光缆等)。这本身就是直线通路的,如果有缓存那就得拥塞啦。就算有,也应该在路由器、交换机上面。
这时,可能又有同学有疑问。在网络通信上不都有接受数据的网络缓冲区吗?用它们来加速的,这不是缓存?
那吒吒辉在就要敲敲黑板啦,缓存和网络缓冲区是不一样的,网络缓冲区是建立在Socket网络通信基础之上的。这玩意儿是提高系统每个单元的利用率和系统吞吐量。从而实现多路复用的。和这里缓存不一样。
啥,你还不清楚!!后面安排下计算机底层的操作系统原理,你就知道啦。谁叫我是暖男一枚呢(* ̄︶ ̄)
例如:
Redis获取数据,首先要建立连接,这时的缓冲区是指,客户端发送Redis指令,首先会先存入自己本地的缓冲区上,然后再通过网卡把数据给整到网络上。
而Redis的服务端也是一样的,它接受数据首先也会把数据暂存在服务端缓冲区里面。然后再获取到Redis服务进行处理。这就是网络缓冲区,也就是针对数据处理的时候,你首先得放到缓冲区里面,在进行存取、发送操作。
这一下子,还把我干懵了,那吒哥,到底什么是网络缓存?
咳咳,你往下看
所谓网络中的缓存,是位于客户端和服务端之间,通过代理或响应客户端的网络请求,从而对重复的请求返回缓存中的数据资源。
同时,接受服务端的请求,更新缓存中的内容。
还不明白?
你这么看 像HTTP请求一般都需要发送到后端的应用服务器获取数据吧,那位于客户端和应用服务端之间是不是就有web服务器,也就是Apache、Nginx等。
换句话来说,就是把一些后端的数据存储在它们上面,从而减少重复请求的响应,因为位于客户端和服务的网络通信之间,故此这么称呼。
吒吒辉,你看那nginx、Apache整的那么到位,还不都需要接受网络请求呀?
这里你需要明白,你当前HTTP请求的目的是干嘛?
是要获取请求的动态数据,所以客户端与服务端之间的距离都算在它们的网络通信上,如果中间有个缓存的地方,即可减少网络响应时间,那就是如下的赶脚:
- PHP的请求,客户端----->nginx----->php-fpm
- JAVA的请求,客户端----->Apache----->Tomcat
这样说大家应该明白吧,忽然感觉自己太温暖啦。累死耕地的牛了
![4c2d63fdeaf87d53f6f15f068c417242.png](https://i-blog.csdnimg.cn/blog_migrate/803ee3aad39e75db0d2fef25278628d6.jpeg)
Web代理缓存
Web代理几乎是伴随着互联网诞生的,常用的Web代理分为 正向代理、反向代理和透明代理。Web代理缓存可理解为Web代理+缓存的一种技术。
正向与反向代理,详情看上篇文章
一般情况下,Web代理默认说的是正向代理, 如下所示。
![cbc4b915af2e4fe1700fc2020df77736.png](https://i-blog.csdnimg.cn/blog_migrate/6a7c9679b2709b432e53e95b961990c7.png)
正向代理
为了从源服务器取得内容,用户 向 代理服务器发送一个请求并指定目标服务器,然后代理服务向源服务器转交请求并将获得的内容返回给客户端。一般,客户端要进行一些特别的设置才能使用正向代理。
反向代理
反向代理与正向代理相反,对于客户端而言代理服务器就像是源服务器,并且客户端不需要进行设置。客户端向反向代理发送普通请求,接着反向代理将判断向何处转发请求,并将从源服务器获得的内容返回给客户端。
透明代理
透明代理的意思是客户端根本不需要知道有代理服务器的存在,由代理服务器改变客户端请求的报文字段,并会传送真实的IP地址。加密的透明代理属于匿名代理,不用设置就可以使用代理了。透明代理的例子就是时下很多公司使用的行为管理软件。
它是介于交换机和防火墙之间的一种设备,用户的上网行为都会交由它来进行流控、限速、工作网址的屏蔽等操作。
不知道你家公司有这个软件没得呢?折磨人
这里所谓的Web代理缓存是指使用正向代理的缓存技术。Web代理缓存的作用跟浏览器的内置缓存类似,只是介于浏览器和互联网之间。简单点就是把上游服务的数据,缓存到代理软件处。
当通过代理服务器进行网络访问时,浏览器不是直接到Web服务器去取回网页而是向Web代理发出请求,由代理服务器来取回浏览器所需要的信息并传送给浏览器。
而且,Web代理缓存有很大的存储空间,不断将新获取的数据储存到本地的存储器上,如果浏览器所请求的数据在Web代理的缓存上已经存在而且是最新的,那么就不重新从Web服务器取数据,而是直接将缓存的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。
对于企业而言,使用Web代理既可以节省成本,又能提高性能。
![d01ff1b7468b5dbb86b10b18a457499c.png](https://i-blog.csdnimg.cn/blog_migrate/89aa7e83eda99e1120bba5a5c6217866.png)
对于Web代理缓存而言,较流行的是Squid,它支持建立复杂的缓存层级结构,拥有详细的日志、高性能缓存以及用户认证支持。Squid同时支持各种插件。
例如:
Squid Guard就是一个提供URL过滤的插件,对于屏蔽某些站点和内容十分有用。如果需要分析Squid的各种指标,可选择 webalizer 。如果有兴趣的话,可以进一步了解一下 Squid 的内部机制。它不仅可以作为正向代理还可以作为反向代理。如下是内部机制工作图:
Squid 架构工作原理解析
Squid 的部署模式:child、sibling、parent。
关系如下:
- Child 和 Parent关系(父子级模式):当 Child Squid Server 没有资料时,会直接向 Parent Squid Server 要资料,然后一直等,直到 Parent 给它资料为止。
父子级模式通信配置简述
icp_access allow all #开启所有的icp权限
cache_peer 192.168.1.50 parent 81 0 no-query originserver weight=1 name=a
cache_peer_domain a www.zhazhahui.com
- Sibling 和 Sibling关系(邻居模式):当 Squid Server 没有资料时,会先向 Sibling 的 Squid Server 要资料,如果 Sibling 没资料,就跳过它直接向 Parent 要或上 internet 去拿。也就是多台机器部署,相互实现通信。
注:关系是通过配置文件来进行指定,各个Squid 服务之间通信关系
icp_access allow all #开启所有的icp权限
cache_peer 121.9.221.160 parent 80 0 no-query no-digest originserver设置源服务器
cache_peer 121.9.221.158 sibling 80 3130 #添加icp通讯的sibling邻居
cache_peer 121.9.221.147 sibling 80 3130 #添加icp通讯的sibling邻居
cache_peer_access 121.9.221.147 allow all #允许icp通讯的sibling邻居通讯
cache_peer_access 121.9.221.158 allow all #允许icp通讯的sibling邻居通讯
cache_peer_domain 121.9.221.160 www.zhazhahui.com #配置本机squid允许接受访问的域名
那Squid的资料如何拿?首先你得看下它是如何存在?
每一台Squid 代理服务器上都有若干颗硬盘,每颗硬盘又分割成多个分区,每一个分区又可建立很多目录,目录下存放文件(Squid 把它叫object)。
当 Squid 获取资料时,会通过查询表的方式来定位某个资源的位置,所查询的表叫 Hash table 和 Digest table;
- Hash table在这里可以称之为目录或者提纲,它记录所有的Digest table表信息。
- Digest table在这里可以称之为摘要或者索引,它记录了磁盘上每个分区,每个目录里存的缓存摘要,
Squid 接受到请求后先查询Hash table,在根据Hash table所指向的Digest table查询需要的信息。
Squid工作模式
首先 Squid 按照上述模式进行部署,然后客户端发送请求到 Squid 服务器,首次磁盘上无缓存数据,直接代理到后端网络服务器获取资源并缓存数据。后续请求直接根据部署的模式在 Squid 上进行内容查找。
边缘缓存
使用Web反向代理服务器和使用正向代理服务器一样,都可达到缓存的作用。反向代理缓存可以缓存原始资源服务器的资源,而不是每次都要向原始资源服务器请求数据,特别是一些静态的数据,比如图片和文件,很多Web服务器就具备反向代理的功能,比如大名鼎鼎的Nginx。
如果反向代理服务器能够做到和用户来自同一个网络,可以将这样的反向代理缓存称为边缘缓存。因为用户访问反向代理服务器,将会得到更快响应速度。
那如何判断用户的网络和代理服务器网络是同一个呢?
客户端在访问到服务端时,是通过 智能DNS 规则 来实现就近访问,就是DNS在解析到客户端访问域名的时候,得到服务器ip,然后拿它与客户端ip进行比较,如果是同一个ip地址段就采用最近的服务器来响应客户端。
简单点原理就是先在DNS上面做好域名和IP段的映射,然后在对比IP查找,相当于数据库找数据。
边缘缓存在网络上位于靠近用户的一侧,可以处理来自不同用户的请求,主要用于向用户提供静态的内容,以减少应用服务器的介入。边缘缓存的一个有名的开源工具就是 Varnish,在默认情况下进行保守缓存。也就是说,Varnish 只缓存它所知的安全内容。Varnish的一个特性是使用虚拟内存,精妙之处在于利用了操作系统的管理机制。Varnish可以高度定制如何处理请求,缓存哪些内容。
如果感兴趣,可以进一步了解Varnish后端的内部机制,如图所示。
说到边缘缓存,那就得就得谈谈它典型的商业化服务 CDN 了,例如:AWS的Cloud Front,我国的ChinaCache等,现在一般的公有云服务商都提供了CDN服务。CDN是Content Delivery Network的简称,即“内容分发网络”的意思。使用CDN之后,客户端与服务器通信如图所示。
![7713d7f4d3fb68ffa8c4d8298febeab1.png](https://i-blog.csdnimg.cn/blog_migrate/98e2cb17aedb58c4b4e8685cac452ea2.png)
使用CDN后,客户端/服务器的通信方式
CDN边缘节点的缓存策略因服务商不同而有所变化,但一般都会遵循HTTP标准协议,通过HTTP响应头中的 Cache-control:max-age 的字段来设置CDN边缘节点数据缓存时间。
当你在CDN提供商控制台添加完加速域名后,会得到一个CDN给您分配的CNAME域名,然后你需要在的DNS解析服务商添加CNAME记录,将自己的加速域名指向这个CNAME域名,这样该域名所有的请求才会都将转向CDN的节点。
客户端请求通过DNS规则解析后,就会拿到你得到CDN节点地址。客户端在向CDN节点请求数据时,CDN节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端;否则,CDN节点就会向源站发出回源请求,从源站拉取最新数据,更新本地缓存,并将最新数据返回给客户端。
CDN服务商一般会提供基于文件后缀、目录等多个维度来指定在CDN上的缓存时间,为用户提供更精细化的缓存管理。
![0712267e17ac196c4a70dc06062b26e1.png](https://i-blog.csdnimg.cn/blog_migrate/8b13c18c9154535b38539f072fbc6cff.jpeg)
CDN回源率的影响因素
若数据在CDN上的缓存时间较短,则CDN边缘节点上的数据会经常失效,导致频繁回源,增加了源站的负载,同时也增大了访问延时;若数据在CDN上的缓存时间太长,会带来数据更新时间慢的问题。开发者需要针对各自特定的业务,来做特定的数据缓存时间管理。影响CDN缓存条件如下:
缓存时间会对“回源率”产生直接的影响
源站动态资源较多,多为不可缓存的内容,也会导致频繁回源拉取。
资源访问量较低,文件热度不够,CDN 收到请求较少无法有效命中缓存。此时缓存内容可能已经过期。
访问资源的 URL 带参数,并且参数不断变化,当用不同的 URL 去访问 CDN 的时候,CDN 会认为这是一个新请求(即便这两个不同的 URL 其实是访问到了同一个文件,并且该文件已经缓存在节点上),也会回源去拉取所请求的内容。
有什么些方式可及时更新CDN缓存呢?
一般,CDN边缘节点对开发者来说是透明的,开发者可以通过CDN服务商提供的“刷新缓存”接口来清理位于CDN边缘节点上的缓存数据。这样开发者在更新数据后,可以使用“刷新缓存”功能来强制要求CDN边缘节点上的数据缓存过期,保证客户端在访问时,拉取到最新的数据。
除开拉模式,还存在推模式,就是当源数据发生变化后,直接推送给CDN缓存服务器。常见的就是你在后端控制里面设置了CDN缓存内容,会自动做更新,后续在继续分享这个原理内容。
总结
- 网络缓存本质是减少请求响应之间的网络时间,也就是常说的正、反向代理。
- 正向代理就是知道应用服务器所在位置,反向代理不知道,分别对应外与内网应用。
- CDN的回源影响因素文件缓存时间、URL参数时常变化、访问量过低、动态源过多等,CDN资源获取可采用推与拉模式
哈喽,我是吒吒辉,就爱分析进阶相关知识,如果觉得文章对你有帮助,欢迎分享给你的朋友,也给小吒点个「在看」。同时也可入群参加【知识盛宴】,听说里面有阿里、顺丰等人额。每天一个瓶颈问题,快速迭代成长自己。也可直接回复【知识}获取知识盛宴pdf
![73b938ab53332e75e1fdfb39882f30a7.png](https://i-blog.csdnimg.cn/blog_migrate/32e6596ac5fb9c7c745758f124f8b8b2.jpeg)