微服务架构中的多级缓存设计还有人不懂?
今天我们来聊聊缓存这个话题,看看在微服务环境下如何设计有效的多级缓存架构。主要涉及三方面内容:Web应用的客户端缓存;应用层静态资源缓存;服务层多级缓存。
首先,咱们先讲解微服务架构的多级缓存设计。微服务架构中的多级缓存设计
提到缓存,想必每一位软件工程师都不陌生,它是目前架构设计中提高性能最直接的方式。这里我们举个例子:
假设应用程序将原始数据存储在MySQL数据库中。众所周知MySQL数据库会将数据存储在硬盘以防止掉电丢失,但是受制于硬盘的物理设计,即便是目前性能最好的企业级SSD硬盘,也比内存的这种高速设备IO层面差一个数量级,而以淘宝、京东这种电商为代表的互联网应用,都是典型的读多写少的场景,因此我们需要在设计上进行数据的读写分离,在数据写入时直接落盘处理,而占比超过90的数据读取操作时则从以Redis为代表的内存NoSQL数据库提取数据,利用内存的高吞吐瞬间完成数据提取,这里Redis的作用就是我们常说的缓存。
当然,缓存可不只有用内存替代硬盘这一种形式,在分布式架构下缓存在每一层都有自己的设计,下面咱们通过这个微服务的多级缓存架构图为主线进行讲解。
这张图从上到下包含四层,分别为:客户端、应用层、服务层以及数据层。客户端缓存
X商城客户端为浏览器,在浏览器层面我们主要是对HTML中的图片、CSS、JS、字体这些静态资源进行缓存。
我们以百度Logo图片为例,百度在HTTP通过Expires响应头控制静态图片的有效期。Expires代表过期时间。当前百度Logo的过期时间为2031年2月8日9时26分31秒。在这个时间段内,浏览器会将图片以文件形式缓存在本地,再次访问时会看到fromdiskcache的提示,此时浏览器不再产生与服务器的实际请求,会从本地直接读取缓存图片。通过在浏览器端设置Expires可以在很大程度减少重复请求静态资源带来的带宽损耗,这在高并发Web应用中是基础而重要的设置。应用层缓存
那Expires到底在哪里进行设置呢?对于浏览器来说它只是客户端,只负责读取Expires响应头,对于Expires要在应用层,也就是CDN与Nginx中进行设置。CDN内容分发网络
CDN全称是ContentDeliveryNetwork,即内容分发网络,是互联网静态资源分发的主要技术手段。
CDN内容分发网络
中国幅员辽阔,从北京到上海就有上千公里,如果大量的上海用户同时要访问千里之外的北京服务器的资源,这么长的通信必然带来高延迟与更多不可控因素影响数据传输,如果有某种机制允许将北京的静态文件缓存到上海的服务器,上海用户自动就近访问服务器获取资源,这样便可很大程度降低网络延迟,进而提高系统的可用性。而刚才提到的分布式缓存技术就是我们常提到的CDN(内容分发网络)。
对于广域的互联网应用,CDN几乎是必需的基础设施,它有效解决了带宽集中占用以及数据分发的问题。像Web页面中的图片、音视频、CSS、JS这些静态资源,都可以通过CDN服务器就近获取。
CDN技术的核心是智能DNS,智能DNS会根据用户的IP地址自动确定就近访问CDN节点,咱们以下图为例:
以某上海用户的浏览器要访问商城首页广告位的banner。jpg文件,浏览器通过服务商提供的智能DNS服务,将请求自动转发到商城在上海地区准备的CDN服务器,上海CDN收到请求后首先检查本机是否已缓存过banner。jpg,如果文件已存在便直接将图片数据返回给客户端;如果没有缓存过,则回源到北京的源数据节点,将banner。jpg文件抽取并缓存到上海服务器,最后上海CDN节点再将本机的banner。jpg返回给客户端。对于banner。jpg来说,第一次访问后上海CDN节点已缓存该文件,则之后的缓存有效期内所有后续访问由上海CDN直接提供。与之类似的,商城应用可以在重要城市搭建CDN节点,这样原本集中被发往北京服务器的请求就被分摊到CDN节点,这也直接降低了北京机房的带宽压力。
在互联网应用中,因为CDN涉及多地域多节点组网,前期投入成本较高,更多的中小型软件公司通常会选择阿里云、腾讯云等大厂提供的CDN服务,通过按需付费的方式降低硬件成本。而这些服务商又会为CDN赋予额外的能力,比如阿里云、腾讯云CDN除了缓存文件之外,还提供了管理后台能为响应赋予额外的响应头。如下所示在阿里云CDN后台,就额外设置了CacheControl响应头代表缓存有效期为1小时。这里我们额外提一下Expires与的CacheControl的区别,Expires是指定具体某个时间点缓存到期,而CacheControl则代表缓存的有效期是多长时间。Expires设置时间,CacheControl设置时长,根据业务场景不同可以使用不同的响应头。
Nginx缓存管理
说完CDN,下面再来聊一下Nginx。Nginx是一款开源的、跨平台的高性能Web服务器,它有着高性能,稳定性好,配置简单,模块结构化,资源消耗低的优点。同时支持反向代理、负载均衡、缓存的功能。Nginx是Web应用架构中的常客,例如后端Tomcat集群便可通过增加Nginx前置做软负载均衡,为应用提供高可用特性。
在互联网应用中,用户分布在全国各地,对资源的响应速度与带宽要求较高,因此部署CDN是十分有必要的。但在更多的企业应用中,其实大部分的企业用户都分布在指定的办公区域或者相对固定的场所,再加上并发用户相对较少,其实并不需要额外部署CDN这种重量级解决方案。在架构中只需要部署Nginx服务器,利用Nginx自带的静态资源缓存与压缩功能便可胜任大多数企业应用场景。
在Nginx中自带将后端应用中图片、CSS、JS等静态资源缓存功能,我们只需在Nginx的核心配置nginx。conf中增加下面的片段,便可对后端的静态资源进行缓存,关键配置我已做好注释,同学们可以直接使用。设置缓存目录levels代表采用1:2也就是两级目录的形式保存缓存文件(静态资源css、js)keyszone定义缓存的名称及内存的使用,名称为babytuncache,在内存中开始100m交换空间inactive7d如果某个缓存文件超过7天没有被访问,则删除maxsize20g;代表设置文件夹最大不能超过20g,超过后会自动将访问频度(命中率)最低的缓存文件删除proxycachepathd:nginxcachelevels1:2keyszonebabytuncache:100minactive7dmaxsize20g;配置xmall后端服务器的权重负载均衡策略upstreamxmall{server192。168。31。181weight5maxfails1failtimeout3s;server192。168。31。182weight2;server192。168。31。183weight1;server192。168。31。184weight2;}server{nginx通过80端口提供Web服务listen80;开启静态资源缓存利用正则表达式匹配URL,匹配成功的则执行内部逻辑代表URL匹配不区分大小写location。(gifjpgcsspngjswoffhtml)(。){配置代理转发规则proxypasshttp:xmall;proxysetheaderHosthost;proxysetheaderXForwardedForproxyaddxforwardedfor;proxycachexmallcache;如果静态资源响应状态码为200(成功)302(暂时性重定向)时缓存文件有效期1天proxycachevalid20030224h;301(永久性重定向)缓存保存5天proxycachevalid3015d;其他情况proxycachevalidany5m;设置浏览器端缓存过期时间90天expires90d;}使用xmall服务器池进行后端处理location{proxypasshttp:xmall;proxysetheaderHosthost;proxysetheaderXForwardedForproxyaddxforwardedfor;}}复制代码
增加上面配置后,每一次通过Nginx访问应用中新的静态文件时,在Nginx服务的缓存目录便会生成缓存文件,在缓存有效期内该静态资源的请求便不再送到后端服务器,而直接由Nginx读取本地缓存并返回。
服务层缓存
在前面无论是CDN还是Nginx,都是对Web应用中的静态资源文件进行缓存。但后端应用与服务更多的是访问接口与数据,对于这些对象我们如何利用缓存技术进行性能优化呢?对于后端应用与服务的缓存可以按部署方式分为进程内缓存与分布式缓存服务。进程内缓存
所谓进程内缓存,就是在应用中开辟的一块内存空间,数据在运行时被载入这块内存,通过本地内存的低延迟、高吞吐的特性提高程序的访问速度。进程内缓存在众多Java框架内都有广泛应用,例如Hibernate、Mybatis框架的一二级缓存、SpringMVC的页面缓存都是进程内缓存的经典应用场景,这些进程内缓存在Java中也有着非常多优秀的开源实现,如EhCache、Caffeine都是代表性产品。分布式缓存服务
与进程内相对的,就是需要独立部署的分布式缓存服务。最常用的是基于Redis这种内存型NoSQL数据库,对整体架构中的应用数据进行集中缓存。
在架构设计时,很多新架构师一听到缓存,下意识认为增加Redis分布式缓存服务器就够了,其实这是片面的做法。在缓存架构设计时,一定要按照由近到远、由快到慢的顺序进行逐级访问。假设在电商进行商品秒杀活动时,如果没有本地缓存,所有商品、订单、物流的热点数据都保存在Redis服务器中,每完成一笔订单,都要额外增加若干次网络通信,网络通信本身就可能由于各种原因存在通信失败的问题。即便是你能保证网络100可用,但Redis集群承担了来自所有外部应用的访问压力,一旦突发流量超过Redis的负载上限,整体架构便面临崩溃的风险。
因此在Java的应用端也要设计多级缓存,我们将进程内缓存与分布式缓存服务结合,有效分摊应用压力。在Java应用层面,只有EhCache的缓存不存在时,再去Redis分布式缓存获取,如果Redis也没有此数据再去数据库查询,数据查询成功后对Redis与EhCahce同时进行双写更新。这样Java应用下一次再查询相同数据时便直接从本地EhCache缓存提取,不再产生新的网络通信,应用查询性能得到显著提高。
保障缓存一致性
但事无完美,当引入多级缓存后,我们又会遇到缓存数据一致性的挑战,以下图为例:
我们都知道作为数据库写操作,是不通过缓存的。假设商品服务实例1将1号商品价格调整为80元,这会衍生一个新问题:如何主动向应用程序推送数据变更的消息来保证它们也能同步更新缓存呢?
相信此时你已经有了答案。没错,我们需要在当前架构中引入MQ消息队列,利用RocketMQ的主动推送功能来向其他服务实例以及Redis缓存服务发起变更通知。
如上图所示,在商品服务实例1对商品调价后,主动向RocketMQBroker发送变更消息,Broker将变更信息推送至其他实例与Redis集群,这些服务实例在收到变更消息后,在缓存中先删除过期缓存,再创建新的数据,以此保证各实例数据一致。
看到这里你会发现,对于缓存来说,并没有终极的解决方案。虽然多级缓存设计带来了更好的应用性能,但也为了缓存一致性必须引入MQ增加了架构的复杂度。那到底多级缓存设计该如何取舍呢?在我看来,有三种情况特别适合引入多级缓存。
第一种情况,缓存的数据是稳定的。例如邮政编码、地域区块、归档的历史数据这些信息适合通过多级缓存减小Redis与数据库的压力。
第二种情况,瞬时可能会产生极高并发的场景。例如春运购票、双11零点秒杀、股市开盘交易等,瞬间的流量洪峰可能击穿Redis缓存,产生流量雪崩。这时利用预热的进程内缓存分摊流量,减少后端压力是非常有必要的。
第三种情况,一定程度上允许数据不一致。例如某博客平台中你修改了自我介绍这样的非关键信息,此时在应用集群中其他节点缓存不一致也并不会带来严重影响,对于这种情况我们采用T1的方式在日终处理时保证缓存最终一致就可以了。
以上是我总结的三种适合服务层做多级缓存的场景。当然如果你们的应用并发量不大,在未来的12年内利用Redis分布式缓存集群完全可以胜任应用性能要求,那自然就没有必要设计多级缓存,我们要根据业务特点灵活调整架构。小结
今天咱们介绍了在应用微服务架构下从客户端到服务层,各层的缓存设计以及解决方案,讲解了从浏览器的Expires响应头到CDN、Nginx的静态资源缓存,再到服务层针对数据的多级缓存,使你对微服务架构的缓存有了总体的了解。
原文链接:https:juejin。cnpost7202479313228218428
祝你好孕用心守护早到天使,让爱走得更长远每位粑粑麻麻都盼星星盼月亮期待小天使快快降生但并不希望他她还没足月就来到世上如何预防宝宝早产宝宝一旦早产怎么办,出生后如何护理11月17日世界早产儿日来临之际带你一文解读早产儿什么
你真的什么办法都试过吗?降服神兽,应该使出浑身解数文Rhine图部分来自pixabay前段时间,我和一位久未谋面的女性朋友L喝下午茶。掐指一算,因为疫情的缘故,分布两地的我们居然已经整整三年没有见过面了。三年前,L因为羊水早破紧急
这3种现象才是导致脚部开裂的原因,记得对症下药,才能拔除病源很多人都会有一些足下的难言之隐,譬如一个很普遍的现象,那就是脚后跟会有死皮和龟裂。有的人会说这是缺乏维生素的表现,还有些人看热闹不嫌事大,说这是身体高尿酸的表现,很可能会患上类风湿
咳嗽变异性哮喘一高发人群1儿童发病率较高,已发现30以上的儿童干咳与咳嗽变异性哮喘你有关。2成人中,咳嗽变异性哮喘发病率年龄较典型哮喘高,约有13患者年龄大于50岁,中年女性较多见。二患病率新近
童心沐党恩共筑强军梦童心沐党恩共筑强军梦番禺区人武部以开展国防教育进校园活动抓好党的二十大精神贯彻落实文丨吕自强为抓好党的二十大精神强军篇教育篇在基层的贯彻落实,进一步深化全民国防教育,丰富广大学生的
生完二胎,我却和妻子分房睡秋日生活打卡季斟酌再三,还是决定生二胎2020年我们家大宝5周岁,我和老婆考虑很久,也一本正经的做了SWOT分析,分析下来决定生二胎。主要原因是大宝现在年龄不大,两个人可以陪伴成长
如何让汉语拼音教学变得更有趣?汉语拼音是学习普通话发音的标准,因此对想学好拼音的学生甚至大人而言极为重要。然而,对许多刚升入小学一年级的孩子而言,学习汉语拼音往往是语文中最枯燥乏味的内容之一。学习汉语拼音不像阅
想你和作死有区别吗!潘粤明疑似表白董洁,至今未删恩爱记录17日凌晨3点,演员潘粤明在社交平台突然发文。想你和作死有什么区别吗?如此直接大胆的表白,瞬间引来众多网友热议。在评论区,有人调侃他把社交平台当朋友圈了。有人夸赞他,是难得的内娱活
85岁马玉琴穿一身粉逛街,全程专人跟拍,李玉成大肚便便遭嘲讽马玉琴夫妻俩在网络上,是小有名气的老妻少夫组合,他们两人年龄相差32岁,中间隔了足足一辈人。马玉琴如今已经85岁,容颜衰老鹤发鸡皮,李玉成却只有53岁。巨大的年龄差,导致马玉琴和李
杨幂直播又被群嘲,开美颜滤镜难掩脸垮显老态,和写真照判若两人近日,杨幂的新剧爱的二八定律播出持续引发外界热议,关于杨幂在剧中的状态饱受争议,尤其眼窝凹陷感觉特别憔悴和疲惫,一向冻龄的少女幂如今状态大不如前,不过对于外界的争议,杨幂并未给出回
夭折婴儿父亲李宝亮亲述更多细节,更让人怒火第1个细节李宝亮一家从周口去郑州是给3个多月的孩子治病,不是什么乱跑旅游。有人怀疑李宝亮为什么在疫情严重时还带孩子去郑州。原来李宝亮是河南省周口市淮阳区人。女儿6月29日出生,也就
改善熬夜肌,贝妮芙小金瓶让肌肤重拾细腻美感随着生活节奏的不断加快,越来越多的人因工作而常常熬夜,久而久之,皮肤状态就会越来越差,出现一系列问题,如皮肤暗沉皮肤粗糙毛孔粗大等,这样一来,就会直接影响到颜值,哪怕是通过化妆的方
我一定会去,隐居深山,修得正果等你老了以后,你会想去大山深处隐居吗?我看了很多友友的讨论!我如果是一个人的话,我一定去深山里隐居,远离这个罪恶的红尘世界。人与人之间没有了以前的信任,也没有了真爱,没有钱女人能喜
假如可以生命可以重来当你走到生命尽头,如果用你今生的所有经历换取你的重生,再让你活一遍,你愿意吗?不愿意!因为我已经厌倦了人们的勾心斗角和尔虞我诈,其实在我的前半生我深刻悟出一个道理,在一个世界上当你
一池碧波一片山,往事已远情可追,独居深山盼伊归深秋的蜀山。高山中的山沟里有一个静寂的小院落。肆意生长,绿意深深的竹林和树林将这院落掩藏其中。如一个饱经沧桑的老人,独自守着心底的往事,在岁月中渐渐走向生命的尽头。一条蜿蜒曲折的山
幸福的人,都拥有这5种好心态01平心静气,清风自来生活有起有落,日子有酸有甜。遇到问题时,如果脾气暴躁着急上火,不仅不能从根本上解决问题,还可能火上浇油。心态好的人遇事时,能透彻地看到问题根源,想明白合适的处
虽千万人,吾往矣纵然面对千万人(阻止),我也勇往直前。这是虽千万人,吾往矣的解释,出自公孙丑问孟子的一段话。初读此句,只感受到言者的决心,像是上阵前的口号一般。但是随着对孟子的了解,我发现对句子的
失去的不再拥有失去后愧,生活中人人都会有这样的经历。很多人却忽略了不再拥有,由其是人物的价值。今天,就从一颗牙齿说起。六岁的童年,雪白的乳牙被恒牙所替代。伴随着我七十年的人生疾驶而去。恒牙,唇齿
初冬进补,别忘了喝这碗汤,三九补一冬,来年无病痛,家里就能做在寒冷的冬季,能喝上一碗热乎乎的汤,简直是人生一大幸事,俗话说三九补一冬,来年无病痛,在冬季好好地滋补身体,对于下一年的身体健康来说是非常重要的,今天我给大家推荐一个适合在冬季服用
赵露思生图暴露身材比例,撞脸韩星张元英,全身照一出更加尴尬经历过之前珠宝活动的造型争议,95后小花赵露思痛改前非,穿着一身缕空黑色长裙再次迎战,然而似乎效果不佳,不但生图暴露身材比例,还因为撞脸韩星张元英引发争议,被吐槽整个人仿佛张元英仿
冬吃萝卜,糖友可别吃错颜色俗话常说冬吃萝卜夏吃姜,不劳医生开药方。对于糖友们来说,吃萝卜的好处也非常多。但是这么多种萝卜,到底该如何选择?这些萝卜的不同功效,您真的都了解吗?01hr红萝卜红萝卜,也叫胡萝卜
美妆细节第八弹仙女们,一定要答应我!你不护肤没关系,不用大牌也没关系,但是,只要用,至少用有国家批准文号的产品,哪怕超市卖的旁氏妮维雅都可以,至少保证是安全的。像某些三无品牌,朋友圈面膜,不明来