QPS第二级削峰—流量网关+Nginx+lua+Redis+模板引擎

摘要:
我们思考下,除了CDN,在流量打到Tomcat前,还有一道Nginx,那么Tomcat前面一层的Nginx能做啥?  终极解决方案:Nginx+Lua+redis+模板引擎+热点数据缓存架构优化的设计:1、Nginx支持内嵌Lua脚本做Lua_lru_cached缓存,Lua从Redis拉取热点数据,比如Redis有1亿条数据,Nginx集群有50台,我们希望每台Nginx能承载200w的热点数据,而不是全量热点数据Nginx1:1-200w的商品信息Nginx2:200w-200w的商品信息...Nginx50:将热点数据从Redis取回后,通过Lua的Json操作,把数据提前填充到Html模板文件,形成一个完整的Html文件。

QPS第二级削峰—流量网关+Nginx+lua+Redis+模板引擎第1张

  LVS+Nginx动静分离
上文聊到,对用户入口流量的第一级控制,其实就是DNS智能解析,搭配一个负载均衡器LVS或Nginx,配合Keepalived做到入口高可用,代理或转发请求到Nginx节点,做负载均衡,并从Nginx节点上获取  html资源。
但此时需要思考一个问题?
在html上请求到的都是静态资源,即页面上不变的资源,而动态需要变化的数据比如价格,实时的库存,商家上新的型号等等怎么处理?
Nginx动静分离或许是个OK的答案?
  Nginx动静分离,即对静态资源的请求直接由Nginx这一层做响应,动态请求负载均衡到后端Tomcat
但对于双十一的高并发流量,所有动态请求都打到Tomcat是否合适?
我们希望在流量打到后端Tomcat前,有办法在前面响应到这部分动态数据,那么能想到的是流量在Tomcat前经过了CDN和LVS+Nginx
我们首先试图从CDN着手解决问题
我们希望在CDN也能存储页面的一些动态数据,以页面渲染解析能接受的JSON格式存在,这样流量对于动态数据的请求就能在CDN这一层解决,而这部分JSON格式的动态数据来源,只能是来自于能访问  DB数据库的后台服务,如下图
1、面向商家的商品服务,修改商品的动态数据如价格,库存,型号等,编辑完成后触发投递修改数据到MQ
2、文件服务消费MQ后,生成json文件,将这部分商品数据同步到源站存储,同时清除CDN上的文件缓存
3、这样客户对于动态数据的请求,也能在CDN侧做到流量的控制,不会直接打到后端Tomcat,浏览器在从CDN取到动态数据的json文件后,完成解码,取数和渲染
QPS第二级削峰—流量网关+Nginx+lua+Redis+模板引擎第2张 
什么样的系统适合这样的方案?
1、价格不常变化的——价格变化需要重新生成Json文件,同步到CDN源站,并且清除原有CDN缓存
2、商品数量不多——如果是淘宝&京东亿级数量的商品,则CDN既需要缓存静态资源文件,又得缓存N*亿级的Json文件,压力会很大
此架构比较适合:
旅游电商网站——价格按旅游旺季和淡季变化,旅游商品的套餐不会太多
瓜子二手车——价格车主定价后一般改动不大,二手车市场也不会有亿级的数量级
那么如果是淘宝和京东这样双十一高并发的流量,需要怎样的架构才合适?
我们思考下,除了CDN,在流量打到Tomcat前,还有一道Nginx,那么Tomcat前面一层的Nginx能做啥?
1、存放html,css,js等静态资源文件
2、写Lua脚本实现带业务逻辑的流量分发等...
3、做请求的反向代理
4、利用tmpfs做磁盘和内存的映射
而LVS+Nginx集群的架构,可以承载住一个地区范围内很高流量的并发,
基于此,我们想到是否能在后台Tomcat实时生成Html文件,即从DB查询到动态数据,填充到模板中,返回到Nginx中缓存,Nginx中开启可映射磁盘和内存的tmpfs,缓存html文件,下次再有请求访问,则直  接从Nginx这一层响应请求,这样基于LVS+Nginx的结构,分担了CDN的大部分压力,看似是可取的。
QPS第二级削峰—流量网关+Nginx+lua+Redis+模板引擎第3张
这个解决方案存在的三个问题
1、生成文件并响应的过程是否会很耗时?
2、如果所有页面的请求都打到一台Nginx上,则这个Nginx要承担全量Html页面的缓存,Nginx扛得住这么多文件的缓存吗?
3、Nginx上html文件的治理问题,比如更新,修改,页面过期的删除
所以我们需要再往一个方向去思考,有没有不需要生成文件的,不需要文件治理的,Nginx上能均匀的散落html文件的方案。
  终极解决方案:Nginx+Lua+redis+模板引擎+热点数据缓存
QPS第二级削峰—流量网关+Nginx+lua+Redis+模板引擎第4张
架构优化的设计:
1、Nginx支持内嵌Lua脚本做Lua_lru_cached缓存,Lua从Redis拉取热点数据,比如Redis有1亿条数据,Nginx集群有50台,我们希望每台Nginx能承载200w的热点数据,而不是全量热点数据
Nginx1:1-200w的商品信息
Nginx2:200w-200w的商品信息
...
Nginx50:
将热点数据从Redis取回后,通过Lua的Json操作,把数据提前填充到Html模板文件,形成一个完整的Html文件。
2、如果LVS的负载均衡策略为IP哈希,那么假设商品id=30的请求打过来,通过IP哈希可能负载到多台不同的Nginx服务器上,这里导致的问题可能有:
(1)Nginx没有这件商品数据的话,每次都得去Redis拉取,造成了穿透
(2)Nginx上的数据一致性问题,比如Nginx节点1的商品id=1的数据和Nginx节点2的数据商品id=1的数据缓存失效时间不同,那么LB打到两台Nginx上得到的数据就不一致了
我们希望在LVS这一层做编程,实现对商品id的哈希,使之均匀的分布到Nginx服务器上,所以需要把LVS这一层替换成可编程的流量网关kong或openresty,这两者都是基于Nginx封装的高性能网关
3、对于写请求,比如下单,支付等操作,可通过Nginx上的Lua编程,扔到消息队列RocketMQ上去,通过异步操作和后端微服务消费保证数据的最终一致性
4、不同地区数据中心的数据一致性,通过地区拉专线来保证

免责声明:文章转载自《QPS第二级削峰—流量网关+Nginx+lua+Redis+模板引擎》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇oracle12C的数据库安装编写通用shell脚本启动java项目,适用于多数服务,只需修改服务名即可下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Redis系列文章总结:ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁

引言:最近回头看了看开发的.Net Core 2.1项目的复盘总结,其中在多处用到Redis实现的分布式锁,虽然在OnResultExecuting方法中做了防止死锁的处理,但在某些场景下还是会发生死锁的问题,下面我只展示部分代码: 问题: (1)这里setnx设置的值“1”,我想问,你最后del的这个值一定是你自己创建的吗? (2)图中标注的步骤1和步...

nginx --反向代理配置文件

配置文件如下图   server { listen 8080; server_name 0.0.0.0;//这里可以配置相应域名 root /www/facei; index index.html index.htm; access_log /var/log/nginx/facei.access.l...

react-router-cache-router

转载---官方文档:https://github.com/CJY0208/react-router-cache-route/blob/master/README_CN.md CacheRoute 搭配react-router工作的、带缓存功能的路由组件,类似于Vue中的keep-alive功能 React v15+ React-Router v4+ 遇到的...

最新版本容器编排工具rancher-v2.3.3的HA高可用部署

一、准备工作 1.1 操作系统版本 CentOS Linux release 7.6.1810 (Core) 1.2 节点信息 节点名称 ip 安装组件 node1 192.168.1.156 etcd, docker, k8s node2 192.168.1.167 etcd, docker, k8s node3 192.168.1.1...

vue使用keep-alive缓存页面,返回页面时刷新部分数据

作用: 在vue项目中,难免会有列表页面或者搜索结果列表页面,点击某个结果之后,返回回来时,如果不对结果页面进行缓存,那么返回列表页面的时候会回到初始状态,但是我们想要的结果是返回时这个页面还是之前搜索的结果列表,这时候就需要用到vue的keep-alive技术了. 介绍: keep-alive是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免...

【nginx】大文件下载

nginx自带文件读取功能,而且实现地很好。 比如直接读取txt文件,png图片等,用chrome可以直接获取到内容。 但是对于很大的文件,比如有2个G的视频,nginx如何吐出2G的内容呢? 实验: 准备很大的MP4文件(比如2G),nginx搭建好webserver,nginx开启access_log选项(log中要包含下载文件大小,http code...