架构设计(动静分离)
架构设计(重点)
-
把秒杀系统独立出来单独打造一个系统,这样可以有针对性地做优化,例如这个独立出来的系统就减少了店铺装修的功能,减少了页面的复杂度;
-
在系统部署上也独立做一个机器集群,这样秒杀的大流量就不会影响到正常的商品购买集群的机器负载;
-
将热点数据(如库存数据)单独放到一个缓存系统中,以提高“读性能”;
-
增加秒杀答题,防止有秒杀器抢单。
-
进一步的完善:
-
对页面进行彻底的动静分离,使得用户秒杀时不需要刷新整个页面,而只需要点击抢宝按钮,借此把页面刷新的数据降到最少;
-
在服务端对秒杀商品进行本地缓存,不需要再调用依赖系统的后台服务获取数据,甚至不需要去公共的缓存集群中查询数据,这样不仅可以减少系统调用,而且能够避免压垮公共缓存集群。
-
增加系统限流保护,防止最坏情况发生。
-
-
动静分离
-
定义: 其实就是把用户请求的数据(如 HTML 页面)划分为“动态数据”和“静态数据” 。 简单来说,“动态数据”和“静态数据”的主要区别就是看页面中输出的数据是否和 URL、浏览者、时间、地域相关,以及是否含有 Cookie 等私密数据。
-
例子:
- 很多媒体类的网站,某一篇文章的内容不管是你访问还是我访问,它都是一样的。所以 它就是一个典型的静态数据,但是它是个动态页面。
- 我们如果现在访问淘宝的首页,每个人看到的页面可能都是不一样的,淘宝首页中包含 了很多根据访问者特征推荐的信息,而这些个性化的数据就可以理解为动态数据了。
-
如何对静态数据做缓存:
-
你应该把静态数据缓存到离用户最近的地方。例如用户浏览器里,CDN(内容分发网络,部署在各地的边缘服务器上),或者服务端的Cache中。
-
静态化改造就是要直接缓存 HTTP 连接,即系统的静态化改造。如下图,web代理服务器根据url,直接取出对应的header和body返回,这个过程简单得连http协议都不用重新组装,甚至http请求头也不需要解析。
-
-
-
如何分离出动态内容
- URL唯一化。根据商品ID就可以让URL唯一化(即后面加?id=xxx),value就是整个http连接
- 分离浏览者相关的因素(包括是否已登录,登录身份等等),单独分拆,用动态请求获取
- 分离时间因素。服务端输出的时间也通过动态请求获取。
- 异步化地域因素。详情页面上与地域相关的因素做成异步方式获取,当然你也可以通过动态请求方式获取,只是这里通过异步获取更合适。
- 去掉 Cookie。服务端输出的页面包含的 Cookie 可以通过代码软件来删除,如 Web 服 务器 Varnish 可以通过 unset req.http.cookie 命令去掉 Cookie。注意,这里说的去掉 Cookie 并不是用户端收到的页面就不含 Cookie 了,而是说,在缓存的静态数据中不含 有 Cookie。
-
动态内容处理:
- ESI(SSI)方案,即 Edge Side Includes (Server Side Includes)。 在 Web 代理服务器上做动态内容请求,并将请求插入到静态 页面中,当用户拿到页面时已经是一个完整的页面了。这种方式对服务端性能有些影响,但是用户体验较好。
- CSI 方案。即单独发起一个异步 JavaScript 请求,以向服务端获取动态内容。这种方式服务端性能更佳,但是用户端页面可能会延时,体验稍差。
-
动静分离架构
-
实体机单机部署:不用虚拟机或者容器,直接上实体机。优点是可以增加单机的内存容量,提升命中率,缺点是CPU资源浪费,因为JAVA进程很难用完整个cpu,再就是运维复杂。
-
统一Cache层: 将单机的 Cache 统一分离出来,形成一个单独的 Cache 集群。
优点:
- 单独一个 Cache 层,可以减少多个应用接入时使用 Cache 的成本。这样接入的应用只 要维护自己的 Java 系统就好,不需要单独维护 Cache,而只关心如何使用即可。
- 统一 Cache 的方案更易于维护,如后面加强监控、配置的自动化,只需要一套解决方案 就行,统一起来维护升级也比较方便。
- 可以共享内存,最大化利用内存,不同系统之间的内存可以动态切换,从而能够有效应 对各种攻击。
缺点:
- Cache 层内部交换网络成为瓶颈;
- 缓存服务器的网卡也会是瓶颈;
- 机器少风险较大,挂掉一台就会影响很大一部分缓存数据。
-
上CDN
- 需要解决的问题:
- 失效问题:静态页面也可能会失效,需要在秒级时间内,让分布在全国各地的cache同时失效。
- 命中率:CDN过于分散,可能会导致cache命中率低,效率低
- 优点:
- 把整个页面缓存在用户浏览器中;
- 如果强制刷新整个页面,也会请求 CDN;
- 实际有效请求,只是用户对“刷新抢宝”按钮的点击。
- 需要解决的问题:
-