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


      

      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文件后,完成解码,取数和渲染
       
      什么样的系统适合这样的方案?
      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的大部分压力,看似是可取的。
      
      这个解决方案存在的三个问题
      1、生成文件并响应的过程是否会很耗时?
      2、如果所有页面的请求都打到一台Nginx上,则这个Nginx要承担全量Html页面的缓存,Nginx扛得住这么多文件的缓存吗?
      3、Nginx上html文件的治理问题,比如更新,修改,页面过期的删除
      所以我们需要再往一个方向去思考,有没有不需要生成文件的,不需要文件治理的,Nginx上能均匀的散落html文件的方案。
     
      终极解决方案: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文件。
     
      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、不同地区数据中心的数据一致性,通过地区拉专线来保证
  • 相关阅读:
    音频电路设计中的基本知识(-)
    Usart的单线半双工模式(stm32F10x系列)
    RTS与CTS的含义
    NetBIOS与Winsock编程接口
    debian下使用gitosis+gitweb搭建SSH认证的git服务器
    解决:无法将“Add-Migration”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次
    Windows Azure Storage Client Library 2.0 入门
    Windows Azure Table Storage 解决 Guid 查询问题
    EF 报【序列包含一个以上的元素】解决办法
    javascript技巧大全套
  • 原文地址:https://www.cnblogs.com/jiyukai/p/14809447.html
Copyright © 2020-2023  润新知