当前位置:首页 » 文件管理 » web多级缓存

web多级缓存

发布时间: 2023-05-21 10:08:50

A. 现在的微型计算机普遍配置cache是为了解决什么

Caché,是 一种后关系型数据库。能并发访问同一数据的数据库技术。

它独一无二地提供了三核物种整合的、能并发访问同一数据的数据库技术:成熟的对象访问方式,高性能的 SQL 访问方式以及丰富的多维访问。在对象数据、关系型数据以及多维数据视图之间不需要映射,这样就大大节省了开发和运行时间。

(1)web多级缓存扩展阅读

Caché的作用:

(Caché提供了快速 Web 应用开发、高速的事务处理、大规模的扩展性、对事务数据的实时查询。 Caché运行概述对Caché架构和性能进行了深层次的描述。 Caché的技术优势主要在为什么选择Caché这一文档中称述。

在小册子以多维引擎全面整合对象和 SQL 中,你可以了解到后关系型技术更多的优势。 Caché问与答中主要回答了一些关于Caché的常见问题,以及为什么增值商和企业选择Caché来提升他们应用的性能。

熟悉Caché的访问者可能想知道Caché 5 (最新的版本)磨核的情况,请访问有哪些新增和升级的功能。文档Caché:为专业开发者改游液而设计告诉了你Caché是如何满足独立软件开发商需求的。

参考资料来源

网络-Caché

B. 最全从输入URL到浏览器显示页面都发生了什么前端浏览器渲染流程

首先了解一下URL的组成:

从上面的URL可以看出,一个完整的URL包括以下几部分:

1、协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符

2、域名部分:该URL的域名部分为“www..com”。一个URL中,也可以使用IP地址作为域名使用

3、端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口80

4、虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例岁明雹中的虚拟目录是“/news/”

5、文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,乎帆如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名

6、锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分

7、参数部分:从“?”开始到“#”为止之间的部分为参数槐御部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

很多大公司面试喜欢问这样一道面试题, 输入URL到看见页面发生了什么? ,今天我们来总结一下。 简单来说,共有以下几个过程

下面我们来看看具体的细节

输入 www.google.com 网址后,首先在本地的域名服务器中查找,没找到去根域名服务器查找,没有再去 com 顶级域名服务器查找,,如此的类推下去,直到找到IP地址,然后把它记录在本地,供下次使用。大致过程就是 . -> .com -> google.com. -> www.google.com. 。 (你可能觉得我多写 .,并木有,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上)

既然已经懂得了解析的具体过程,我们可以看到上述一共经过了N个过程,每个过程有一定的消耗和时间的等待,因此我们得想办法解决一下这个问题!

DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。

在你的chrome浏览器中输入:chrome://dns/,你可以看到chrome浏览器的DNS缓存。

系统缓存主要存在/etc/hosts(linux系统)中

检查浏览器是否有缓存

通过 Cache-Control 和 Expires 来检查是否命中强缓存,命中则直接取本地磁盘的html(状态码为200 from disk(or memory) cache,内存or磁盘);


如果没有命中强缓存,则会向服务器发起请求(先进行下一步的TCP连接),服务器通过 Etag 和 Last-Modify 来与服务器确认返回的响应是否被更改(协商缓存),若无更改则返回状态码(304 Not Modified),浏览器取本地缓存;


若强缓存和协商缓存都没有命中则返回请求结果。

不知道你们有没有注意这样一件事,你访问http://.com的时候,每次响应的并非是同一个服务器(IP地址不同),一般大公司都有成百上千台服务器来支撑访问,假设只有一个服务器,那它的性能和存储量要多大才能支撑这样大量的访问呢?DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡

TCP 协议通过三次握手建立连接。

翻译成大白话就是:

为什么是3次? :避免 历史 连接,确认客户端发来的请求是这次通信的人。
为什么不是4次? :3次够了第四次浪费

建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。

采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误。失效的连接请求报文段是指:主机A发出的连接请求没有收到主机B的确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。

采用两次握手不行,原因就是上面说的失效的连接请求的特殊情况。而在三次握手中, client和server都有一个发syn和收ack的过程, 双方都是发后能收, 表明通信则准备工作OK.

为什么不是四次握手呢? 大家应该知道通信中着名的蓝军红军约定, 这个例子说明, 通信不可能100%可靠, 而上面的三次握手已经做好了通信的准备工作, 再增加握手, 并不能显着提高可靠性, 而且也没有必要。

第一次握手

客户端发送syn包(Seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:

服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:

客户端收到服务器的SYN ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

要先申请CA证书,并安装在服务器上(一个文件,配置nginx支持监听443端口开启ssl并设置证书路径)

浏览器发送请求;

网站从浏览器发过来的加密规则中选一组自身也支持的加密算法和hash算法,并向浏览器发送带有公钥的证书,当然证书还包含了很多信息,如网站地址、证书的颁发机构、过期时间等。

浏览器解析证书。

验证证书的合法性。如颁发机构是否合法、证书中的网站地址是否与访问的地址一致,若不合法,则浏览器提示证书不受信任,若合法,浏览器会显示一个小锁头。

若合法,或用户接受了不合法的证书,浏览器会生成一串随机数的密码(即密钥),并用证书中提供的公钥加密。

使用约定好的hash计算握手消息,并使用生成的随机数(即密钥)对消息进行加密,最后将之前生成的所有消息一并发送给网站服务器。

网站服务器解析消息。用已有的私钥将密钥解密出来,然后用密钥解密发过来的握手消息,并验证是否跟浏览器传过来的一致。然后再用密钥加密一段握手消息,发送给浏览器。

浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。

发送HTTP请求
首先科补一个小知识,HTTP的端口为80/8080,而HTTPS的端口为443

发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由 请求行 请求抱头 请求正文 组成。
请求行
请求行的格式为 Method Request-URL HTTP-Version CRLF eg: GET index.html HTTP/1.1 常用的方法有: GET , POST , PUT , DELETE , OPTIONS , HEAD 。
常见的请求方法区别
这里主要展示 POST 和 GET 的区别
常见的区别

注意一点你也可以在GET里面藏body,POST里面带参数

重点区别

GET 会产生一个 TCP 数据包,而 POST 会产生两个 TCP 数据包。
详细的说就是:

注意一点,并不是所有的浏览器都会发送两次数据包,Firefox就发送一次

请求报头
请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。

从图中可以看出,请求报头中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段。Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。

请求正文
当使用POST, PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息,例如: 现在的Web应用通常采用Rest架构,请求的数据格式一般为json。这时就需要设置 Content-Type: application/json 。
更重要的事情-HTTP缓存
HTTP属于客户端缓存,我们常认为浏览器有一个缓存数据库,用来保存一些静态文件,下面我们分为以下几个方面来简单介绍HTTP缓存

缓存的规则
缓存规则分为 强制缓存 协商缓存


强制缓存
当缓存数据库中有客户端需要的数据,客户端直接将数据从其中拿出来使用(如果数据未失效),当缓存服务器没有需要的数据时,客户端才会向服务端请求。

又称对比缓存。客户端会先从缓存数据库拿到一个缓存的标识,然后向服务端验证标识是否失效,如果没有失效服务端会返回304,这样客户端可以直接去缓存数据库拿出数据,如果失效,服务端会返回新的数据

强制缓存
对于强制缓存,服务器响应的header中会用两个字段来表明——Expires和Cache-Control。


Expires
Exprires的值为服务端返回的数据到期时间。当再次请求时的请求时间小于返回的此时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差,另一方面,Expires是HTTP1.0的产物,故现在大多数使用Cache-Control替代。


Cache-Control
Cache-Control有很多属性,不同的属性代表的意义也不同。

协商缓存
协商缓存需要进行对比判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。
对于协商缓存来说,缓存标识我们需要着重理解一下,下面我们将着重介绍它的两种缓存方案。
Last-Modified
Last-Modified:服务器在响应请求时,会告诉浏览器资源的最后修改时间。

从字面上看,就是说:从某个时间节点算起,是否文件被修改了

这两个的区别是一个是修改了才下载一个是没修改才下载。
Last-Modified 说好却也不是特别好,因为如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。为了解决这个问题,HTTP1.1推出了Etag。


Etag
Etag:服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)

但是实际应用中由于Etag的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用Etag了。


缓存的优点

不同刷新的请求执行过程
浏览器地址栏中写入URL,回车

F5

Ctrl+F5

服务器处理请求并返回HTTP报文
它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,我使用过的Web服务器有Tomcat, Nginx和Apache等等 HTTP报文也分成三份, 状态码 响应报头 响应报文


状态码
状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:

平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500
常见状态码区别
200 成功
请求成功,通常服务器提供了需要的资源。
204 无内容
服务器成功处理了请求,但没有返回任何内容。
301 永久移动
请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 临时移动
服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
304 未修改
自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
400 错误请求
服务器不理解请求的语法。
401 未授权
请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 禁止
服务器拒绝请求。
404 未找到
服务器找不到请求的网页。
422 无法处理
请求格式正确,但是由于含有语义错误,无法响应
500 服务器内部错误
服务器遇到错误,无法完成请求。
响应报头
常见的响应报头字段有: Server, Connection...。
响应报文
你从服务器请求的HTML,CSS,JS文件就放在这里面

就是 Webkit 解析渲染页面的过程。

这个过程涉及两个比较重要的概念 回流 重绘 ,DOM结点都是以盒模型形式存在,需要浏览器去计算位置和宽度等,这个过程就是回流。等到页面的宽高,大小,颜色等属性确定下来后,浏览器开始绘制内容,这个过程叫做重绘。浏览器刚打开页面一定要经过这两个过程的,但是这个过程非常非常非常消耗性能,所以我们应该尽量减少页面的回流和重绘

这个过程中可能会有dom操作、ajax发起的http网络请求等。

web-socket、ajax等,这个过程通常是为了获取数据

setTimeout、setInterval、Promise等宏任务、微任务队列

当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

会导致回流的操作:

一些常用且会导致回流的属性和方法:

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

JS的解析是由浏览器的JS引擎完成的。由于javaScript是单线程运行,也就是说一个时间只能干一件事,干这件事情时其他事情都有排队,但是有些人物比较耗时(例如IO操作),所以将任务分为 同步任务 异步任务 ,所有的同步任务放在主线程上执行,形成执行栈,而异步任务等待,当执行栈被清空时才去看看异步任务有没有东西要搞,有再提取到主线程执行,这样往复循环(冤冤相报何时了,阿弥陀佛),就形成了Event Loop事件循环,下面来看看大人物

先看一段代码

结果我想大家都应该知道。主要来介绍JavaScript的解析,至于Promise等下一节再说

JavaScript是一门单线程语言,尽管H5中提出了 Web-Worker ,能够模拟实现多线程,但本质上还是单线程,说它是多线程就是扯淡。

既然是单线程,每个事件的执行就要有顺序,比如你去银行取钱,前面的人在进行,后面的就得等待,要是前面的人弄个一两个小时,估计后面的人都疯了,因此,浏览器的JS引擎处理JavaScript时分为 同步任务 异步任务

这张图我们可以清楚看到

js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。 估计看完这些你对事件循环有一定的了解,但是事实上我们看对的没这么简单,通常我们会看到Promise,setTimeout,process.nextTick(),这个时候你和我就懵逼。

不同任务会进入不同的任务队列来执行。 JS引擎开始工作后,先在宏任务中开始第一次循环( script里面先执行,不过我喜欢把它拎出来,直接称其进入执行栈 ),当主线程执行栈全部任务被清空后去微任务看看,如果有等待执行的任务,执行全部的微任务(其实将其回调函数推入执行栈来执行),再去宏任务找最先进入队列的任务执行,执行这个任务后再去主线程执行任务(例如执行```console.log("hello world")这种任务),执行栈被清空后再去微任务,这样往复循环(冤冤相报何时了)

下面来看一段代码

我们看看它的执行情况

具体的执行过程大致就是这样。


C. 高并发,你真的理解透彻了吗


高并发,几乎是每个程序员都想拥有的经验。原因很简单:随着流量变大,会遇到各种各样的技术问题,比如接口响应超时、CPU load升高、GC频繁、死锁、大数据量存储等等,这些问题能推动我们在技术深度上不断精进。

在过往的面试中,如果候选人做过高并发的项目,我通常会让对方谈谈对于高并发的理解,但是能系统性地回答好此问题的人并不多。

大概分成这样几类:

1、对数据化的指标没有概念 :不清楚选择什么样的指标来衡量高并发系统?分不清并发量和QPS,甚至不知道自己系统的总用户量、活跃用户量,平峰和高峰时的QPS和TPS等关键数据。

3、理解片面,把高并发设计等同于性能优化 :大谈并发编程、多级缓存、异步化、水平扩容,却忽视高可用设计、服务治理和运维保障。

4、掌握大方案,却忽视最基本的东西 :能讲清楚垂直分层、水平分区、缓存等大思路,却没意识去分析数据结构是否合理,算法是否高效,没想过从最根本的IO和计算两个维度去做细节优化。

这篇文章,我想结合自己的高并发项目经验,系统性地总结下高并发需要掌握的知识和实践思路,希望对你有所帮助。内容分成以下3个部分:


高并发意味着大流量,需要运用技术手段抵抗流量的冲击,这些手段好比操作流量,能让流量更平稳地被系统所处理,带给用户更好的体验。

我们常见的高并发场景有:淘宝的双11、春运时的抢票、微博大V的热点新闻等。除了这些典型事情,每秒几十万请求的秒杀系统、每天千万级的订单系统、每天亿级日活的信息流系统等,都可以归为高并发。

很显然,上面谈到的高并发场景,并发量各不相同, 那到底多大并发才算高并发呢?

1、不能只看数字,要看具体的业务场景。不能说10W QPS的秒杀是高并发,而1W QPS的信息流就不是高并发。信息流场景涉及复杂的推荐模型和各种人工策略,它的业务逻辑可能比秒杀场景复杂10倍不止。因此,不在同一个维度,没有任何比较意义。

2、业务都是从0到1做起来的,并发量和QPS只是参考指标,最重要的是:在业务量逐渐变成原来的10倍、100倍的过程中,你是否用到了高并发的处理方法去演进你的系统,从架构设计、编码实现、甚至产品方案等维度去预防和解决高并发引起的问题?而不是一味的升级硬件、加机器做水平扩展。

此外,各个高并发场景的业务特点完全不同:有读多写少的信息流场景、有读多写多的交易场景, 那是否有通用的技术方案解决不同场景的高并发问题呢?

我觉得大的思路可以借鉴,别人的方案也可以参考,但是真正落地过程中,细节上还会有无数的坑。另外,由于软硬件环境、技术栈、以及产品逻辑都没法做到完全一致,这些都会导致同样的业务场景,就算用相同的技术方案也会面临不同的问题,这些坑还得一个个趟。

因此,这篇文章我会将重点放在基础知识、通用思路、和我曾经实践过的有效经验上,希望让你对高并发有更深的理解。


先搞清楚高并发系统设计的目标,在此基础上再讨论设计方案和实践经验才有意义和针对性。

高并发绝不意味着只追求高性能,这是很多人片面的理解。从宏观角度看,高并发系统设计的目标有三个:高性能、高可用,以及高可扩展。

1、高性能:性能体现了系统的并行处理能力,在有限的硬件投入下,提高性能意味着节省成本。同时,性能也反映了用户体验,响应时间分别是100毫秒和1秒,给用户的感受誉梁是完全不同含咐的。

2、高可用:表示系统可以正常服务的时间。一个全年不停机、无故障;另一个隔三差五出线上事故、宕机,用户肯定选择前者。另外,如果系统只能做到90%可用,也会大大拖累业务。

3、高扩展:表示系统的扩展能力,流量高峰时能否在短时间内完成扩容,更平稳地承接峰值流量,比如双11活动、明星离婚等热点事件。

这3个目标是需要通盘考虑的,因为它们互相关联、甚至也会相互影响。

比如说:考虑系统的扩展能力,你会将服务庆老运设计成无状态的,这种集群设计保证了高扩展性,其实也间接提升了系统的性能和可用性。

再比如说:为了保证可用性,通常会对服务接口进行超时设置,以防大量线程阻塞在慢请求上造成系统雪崩,那超时时间设置成多少合理呢?一般,我们会参考依赖服务的性能表现进行设置。

再从微观角度来看,高性能、高可用和高扩展又有哪些具体的指标来衡量?为什么会选择这些指标呢?

2.2.1 性能指标

通过性能指标可以度量目前存在的性能问题,同时作为性能优化的评估依据。一般来说,会采用一段时间内的接口响应时间作为指标。

1、平均响应时间:最常用,但是缺陷很明显,对于慢请求不敏感。比如1万次请求,其中9900次是1ms,100次是100ms,则平均响应时间为1.99ms,虽然平均耗时仅增加了0.99ms,但是1%请求的响应时间已经增加了100倍。

2、TP90、TP99等分位值:将响应时间按照从小到大排序,TP90表示排在第90分位的响应时间, 分位值越大,对慢请求越敏感。

3、吞吐量:和响应时间呈反比,比如响应时间是1ms,则吞吐量为每秒1000次。

通常,设定性能目标时会兼顾吞吐量和响应时间,比如这样表述:在每秒1万次请求下,AVG控制在50ms以下,TP99控制在100ms以下。对于高并发系统,AVG和TP分位值必须同时要考虑。

另外,从用户体验角度来看,200毫秒被认为是第一个分界点,用户感觉不到延迟,1秒是第二个分界点,用户能感受到延迟,但是可以接受。

因此,对于一个 健康 的高并发系统,TP99应该控制在200毫秒以内,TP999或者TP9999应该控制在1秒以内。

2.2.2 可用性指标

高可用性是指系统具有较高的无故障运行能力,可用性 = 正常运行时间 / 系统总运行时间,一般使用几个9来描述系统的可用性。

对于高并发系统来说,最基本的要求是:保证3个9或者4个9。原因很简单,如果你只能做到2个9,意味着有1%的故障时间,像一些大公司每年动辄千亿以上的GMV或者收入,1%就是10亿级别的业务影响。

2.2.3 可扩展性指标

面对突发流量,不可能临时改造架构,最快的方式就是增加机器来线性提高系统的处理能力。

对于业务集群或者基础组件来说,扩展性 = 性能提升比例 / 机器增加比例,理想的扩展能力是:资源增加几倍,性能提升几倍。通常来说,扩展能力要维持在70%以上。

但是从高并发系统的整体架构角度来看,扩展的目标不仅仅是把服务设计成无状态就行了,因为当流量增加10倍,业务服务可以快速扩容10倍,但是数据库可能就成为了新的瓶颈。

像MySQL这种有状态的存储服务通常是扩展的技术难点,如果架构上没提前做好规划(垂直和水平拆分),就会涉及到大量数据的迁移。

因此,高扩展性需要考虑:服务集群、数据库、缓存和消息队列等中间件、负载均衡、带宽、依赖的第三方等,当并发达到某一个量级后,上述每个因素都可能成为扩展的瓶颈点。

了解了高并发设计的3大目标后,再系统性总结下高并发的设计方案,会从以下两部分展开:先总结下通用的设计方法,然后再围绕高性能、高可用、高扩展分别给出具体的实践方案。

通用的设计方法主要是从“纵向”和“横向”两个维度出发,俗称高并发处理的两板斧:纵向扩展和横向扩展。

3.1.1 纵向扩展(scale-up)

它的目标是提升单机的处理能力,方案又包括:

1、提升单机的硬件性能:通过增加内存、 CPU核数、存储容量、或者将磁盘 升级成SSD 等堆硬件的方式来提升。

2、提升单机的软件性能:使用缓存减少IO次数,使用并发或者异步的方式增加吞吐量。

3.1.2 横向扩展(scale-out)

因为单机性能总会存在极限,所以最终还需要引入横向扩展,通过集群部署以进一步提高并发处理能力,又包括以下2个方向:

1、做好分层架构:这是横向扩展的提前,因为高并发系统往往业务复杂,通过分层处理可以简化复杂问题,更容易做到横向扩展。

上面这种图是互联网最常见的分层架构,当然真实的高并发系统架构会在此基础上进一步完善。比如会做动静分离并引入CDN,反向代理层可以是LVS+Nginx,Web层可以是统一的API网关,业务服务层可进一步按垂直业务做微服务化,存储层可以是各种异构数据库。

2、各层进行水平扩展:无状态水平扩容,有状态做分片路由。业务集群通常能设计成无状态的,而数据库和缓存往往是有状态的,因此需要设计分区键做好存储分片,当然也可以通过主从同步、读写分离的方案提升读性能。

下面再结合我的个人经验,针对高性能、高可用、高扩展3个方面,总结下可落地的实践方案。

3.2.1 高性能的实践方案

1、集群部署,通过负载均衡减轻单机压力。

2、多级缓存,包括静态数据使用CDN、本地缓存、分布式缓存等,以及对缓存场景中的热点key、缓存穿透、缓存并发、数据一致性等问题的处理。

3、分库分表和索引优化,以及借助搜索引擎解决复杂查询问题。

4、考虑NoSQL数据库的使用,比如HBase、TiDB等,但是团队必须熟悉这些组件,且有较强的运维能力。

5、异步化,将次要流程通过多线程、MQ、甚至延时任务进行异步处理。

6、限流,需要先考虑业务是否允许限流(比如秒杀场景是允许的),包括前端限流、Nginx接入层的限流、服务端的限流。

7、对流量进行 削峰填谷 ,通过 MQ承接流量。

8、并发处理,通过多线程将串行逻辑并行化。

9、预计算,比如抢红包场景,可以提前计算好红包金额缓存起来,发红包时直接使用即可。

10、 缓存预热 ,通过异步 任务 提前 预热数据到本地缓存或者分布式缓存中。

11、减少IO次数,比如数据库和缓存的批量读写、RPC的批量接口支持、或者通过冗余数据的方式干掉RPC调用。

12、减少IO时的数据包大小,包括采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存key的大小、压缩缓存value等。

13、程序逻辑优化,比如将大概率阻断执行流程的判断逻辑前置、For循环的计算逻辑优化,或者采用更高效的算法。

14、各种池化技术的使用和池大小的设置,包括HTTP请求池、线程池(考虑CPU密集型还是IO密集型设置核心参数)、数据库和Redis连接池等。

15、JVM优化,包括新生代和老年代的大小、GC算法的选择等,尽可能减少GC频率和耗时。

16、锁选择,读多写少的场景用乐观锁,或者考虑通过分段锁的方式减少锁冲突。

上述方案无外乎从计算和 IO 两个维度考虑所有可能的优化点,需要有配套的监控系统实时了解当前的性能表现,并支撑你进行性能瓶颈分析,然后再遵循二八原则,抓主要矛盾进行优化。

3.2.2 高可用的实践方案

1、对等节点的故障转移,Nginx和服务治理框架均支持一个节点失败后访问另一个节点。

2、非对等节点的故障转移,通过心跳检测并实施主备切换(比如redis的哨兵模式或者集群模式、MySQL的主从切换等)。

3、接口层面的超时设置、重试策略和幂等设计。

4、降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;或者核心链路出问题时,有备选链路。

5、限流处理:对超过系统处理能力的请求直接拒绝或者返回错误码。

6、MQ场景的消息可靠性保证,包括procer端的重试机制、broker侧的持久化、consumer端的ack机制等。

7、灰度发布,能支持按机器维度进行小流量部署,观察系统日志和业务指标,等运行平稳后再推全量。

8、监控报警:全方位的监控体系,包括最基础的CPU、内存、磁盘、网络的监控,以及Web服务器、JVM、数据库、各类中间件的监控和业务指标的监控。

9、灾备演练:类似当前的“混沌工程”,对系统进行一些破坏性手段,观察局部故障是否会引起可用性问题。

高可用的方案主要从冗余、取舍、系统运维3个方向考虑,同时需要有配套的值班机制和故障处理流程,当出现线上问题时,可及时跟进处理。

3.2.3 高扩展的实践方案

1、合理的分层架构:比如上面谈到的互联网最常见的分层架构,另外还能进一步按照数据访问层、业务逻辑层对微服务做更细粒度的分层(但是需要评估性能,会存在网络多一跳的情况)。

2、存储层的拆分:按照业务维度做垂直拆分、按照数据特征维度进一步做水平拆分(分库分表)。

3、业务层的拆分:最常见的是按照业务维度拆(比如电商场景的商品服务、订单服务等),也可以按照核心接口和非核心接口拆,还可以按照请求源拆(比如To C和To B,APP和H5 )。


高并发确实是一个复杂且系统性的问题,由于篇幅有限,诸如分布式Trace、全链路压测、柔性事务都是要考虑的技术点。另外,如果业务场景不同,高并发的落地方案也会存在差异,但是总体的设计思路和可借鉴的方案基本类似。

高并发设计同样要秉承架构设计的3个原则:简单、合适和演进。"过早的优化是万恶之源",不能脱离业务的实际情况,更不要过度设计,合适的方案就是最完美的。

作者简介:985硕士,前亚马逊工程师,现大厂技术管理者。

D. 什么是云平台

  • 云平台

    解释如下:

  • 转向云计算(cloud computing),是业界将要面临的一个重大改变。各种云平台(cloud platforms)的出现是该转变的最重要环节之一。顾名思义,这种平台允许开发者们或是将写好的程序放在“云”里运行,或是使用“云”里提供的服务,或二者皆是。至于这种平台的名称,现在我们可以听到不止一种称呼,比如按需平台(on-demand platform)、平台即服务(platform as a service,PaaS)等等。但无论称呼它什么,这种新的支持应用的方式有着巨大的潜力。

    应用平台(application platforms)是如何被使用的。开发团队在创建一个户内应用(on-premises application,即在机构内运行的应用)时,该应用所需的许多基础都已经事先存在了:操作系统为执行应用和访问存储等提供了基础支持;机构里的其他计算机提供了诸如远程存储之类的服务。倘若每创建一个户内应用都得首先构建所有这些基础的话,那么恐怕我们今天看到的应用会少很多。

  • 中文名

  • 云平台

  • 外文名

  • cloud platforms

  • 相关技术

  • 云计算(cloud computing)

  • 别称

  • 按需平台(on-demand platform)

  • 计算

  • 弹性虚拟计算

  • 目录

  • 1三种云服务

  • 2平台一般模型

  • 3户内到云平台

  • 4大企业云平台

  • 5云服务平台

  • 三种云服务

    编辑

    云平台(2)

参考:网页链接

E. 数据库系统概念 怎么样

本书已经是第六版了,不是经典不会这样长盛不衰的。书很好,就是要花时间看了。
《》是经典的数据库系统教科书《Database System Concepts》的最新修订版,全面介绍数据库系统的各种知识,透彻阐释数据库管理的基本概念。本书内容丰富,不仅讨论了关系数据模型和关系语言、数据库设计过程、关系数据库理论、数据库应用设计和开发、数据存储结构、数据存取技术、查询优化方法、事务处理系统和并发控制、故障恢复技术、数据仓库和数据挖掘,而且对性能调整、性能评测标准、数据库应用测试和标准化、空间和地理数据、时间数据、多媒体数据、移动和个人数据库管理以及事务处理监控器、事务工作流、电子商务、高性能事务系统、实时事务系统和持续长时间的事务等高级应用主题进行了广泛讨论。
《》既可作为高年级本科生或低年级研究生的数据库课程教材,也可供数据库领域的技术人员参考。
作者简介Abraham Silberschatz,于纽约州立大学石溪分校获得博士学位,现为耶鲁大学计算机科学Sidney J. Weinberg教授,计算机科学系主任,曾任贝尔实验室信息科学研究中心副主任。他是ACM Fellow 和 IEEE Fellow,曾获得IEEE Taylor L. Booth 教育奖、 ACM Karl V. Karlstrom 杰出教育者奖、ACM SIGMOD 贡献奖和IEEE 计算机学会杰出论文奖。他的研究兴趣包括操作系统、数据库系统、存储系统、网络管理和分布式系统。
Henry F. Korth ,于普林斯顿大学获得博士学位,现为利哈伊大学计算机科学与工程系Weiseman教授,曾任贝尔实验室数据库原理研究中心主任。他是ACM Fellow 和 IEEE Fellow,是VLDB 10年贡献奖的获得者。他的研究兴趣包括为现代计算架构(多核、多线程、多级缓存)设计的数据库算法、基于Web的大型数据仓储、实时数据库系统和并行系统。
S. Sudarshan于威斯康星大学麦迪逊分校获得博士学位,现为印度理工学院计算机科学与工程系教授,曾为贝尔实验室数据库研究组技术人员。他的研究兴趣包括查询处理和优化、关系数据和图结构数据的关键字查询,以及构建和测试数据库应用系统的工具。

F. OA系统如何优化OA以提高访问速度

oa系统的优化,从多方面来处理
比如,云海oa系统的架构是java架构的,采用多级缓存机制,以及h5无刷新浏览方式,再加上web冗兄庆余,漏帆数据库读写分返尘雹离等,可以从多方位的来优化访问速度。

G. 超线程技术

Intel的超线程(Hyper Threading)技术开创性地使用了"逻辑处理器"的技术,给应用带来的影响不仅是以往的CPU主频的提高,更具意义的是性能的显着提升--超线程技术已经被验证,在企业级计算领域,它能够将服务器执行兼容应用的性能提升30%,大大改进了系统响应速度,从而使服务器能够支持更多用户。
当前的操作系统和服务器应用已不再将不同应用的工作负载混为一个数据流,而是分为单独的指令"线程"。在多路服务器中,这些线程分别由不同的处理器来执行,从而性能远远超出了单处理器系统。凭借超线程技术,英特尔至强处理器操作系统和应用而言就是如同是两个独立?逻辑"处理器,能够同时处理两个"线程"。这一能力主要得益于英特尔NetBurst 微架构的不断创新,它使处理器资源得以充分利用。超线程技术使一个物理处理器能够同时执行两个独立的代码流(称为线程)。从体系结构上讲,一个含有超线程技术的IA-32处理器相当于两个逻辑处理器。而其中每个逻辑处理器都有自己的IA-32架构中心,在加电初始化后,每个逻辑处理器都可单独被停止、中断或安排执行某一特定线程,而不会影响芯片上另一逻辑处理器的性能。与传统双路(DP)配置不同(使用两个独立的物理IA-32处理器),在含有超线程技术的处理器,逻辑处理器共享处理器内核的执行资源,其中包括执行引擎、高速缓存、系统总线接口和固件等。
英特尔超线程技术可兼容现有的大多数多线程32位应用和操作系统,因而软件将无需进行重新编译。当前,业界正在展开优化工作,以使服务器应用能够最大限度利用超线程技术的优势,如Web、目录应用、安全应用、电子商务、CRM、协作、ERP/SCM和数据库等。
超线程技术带来的杰出业务优势包括:较高的服务器响应速度和数据处理速度带来出色业务响应能力;更高效地利用处理器可用资源意味着支持更多的员工。
应用程序和操作系统的功能日益丰富,这需要更高的处理能力。病毒扫描、文件加密和电子邮件压缩等IT后台服务使计算基础设施更加稳健,但同时也增大了电脑处理器的负载。从而,现在含有多任务和后台处理的商用计算迫切需要一种新的方法来提高性能,以使系统保持出色的响应能力。超线程技术带来的影响不可低估。英特尔超线程技术引入了台式机,来满足这些需求,使商业用户事半功倍。使用超线程技术,商业用户可以最充分地利用Windows XP的优先多任务体系结构,同时运行多个要求最苛刻的应用程序,并保持系统的响应性。IT部门可以部署台式机后台服务,以使其环境更加安全、高效和易于管御辩举理,同时最大限度地减少对最终用户工作效率的影响。此外,商业用户现在有能力处理以前曾无法处理的任务,如使用SAS进行数据采掘,同时用Excel宏分析数据,或者一边使用Photoshop设计宣传手册,一边使用Adobe Premiere渲染图像。
超线程的优势还不止这些。提高多任务环境中现有软件及多线程应用的性能只是目前的收益。英特尔还正在与开发下一代解决方案的领先软件公司通力合作,将超线程技术的极大优势融入到这些解决方案之中。

Hyper-Threading 超线程技术

超线程从观念上很容易理解,它让一颗物理处理器在使用的时候看起来更象是两个,处理器的资源被分成两个逻辑的部分。对于用户来说,这也意味着让从前那些多用户、多进程、多线程的软件充分发挥效能的环境不再局限于物理多CPU--逻辑CPU也能够起到接近的作用。
尽管超线程技术在P4 Xeon处理器中已经应用了半年有余的时间,但是面对着未来集成了超线程技术的P4级别CPU,我们认为,还是有必要从更深的层次来挖掘超线程的技术细节以及它与P4核心的有效整合。很幸运,在11月初我们找到了Intel于今年2月份发布Xeon之前的一份内部技术资料--66页的Intel超线程技术白皮书,在这份资料中,Intel详细描述了超线程技术的由来镇碧、架构、如何优化以及测试方法和测试数据。在此,灶盯我们愿与读者一起来共享这些知识,以便我们能够一起来更多了解超线程的机理。
一. 应运而生,超线程诞生的背景

各个行业巨大的需求一直是推动CPU按照摩尔定律稳步进行性能提升的主要动力,尤其是在互联网和通讯领域,为了满足这些增长迅速的需求,我们无法再沿用传统的仅提升CPU频率的设计思路。微结构技术被用来从细节上提升CPU的性能,比如超流水线、乱序运行、超标运行、多级缓存等技术都有效的提升了CPU的性能,但是随着这些技术的引入,我们正在使用的CPU也越来越复杂,它集成了越来越多的晶体管并且要求更高的电源供应。实际上,晶体管数量和电源供应增加的速度远远大于处理器性能提升的速度。

过去十年INTEL CPU性能提升与花费比较

我们来看上图,它体现了过去10年Intel CPU性能提升与相应的成本提升速度的比较,为了减少微结构技术给最终比较结果造成的影响,我们假设这四代CPU都在使用同样的制造工艺并且以486的速率作为基准。 在此表中我们可以看出,排除微结构技术的影响,Intel CPU整数运算的性能在这十年提升了5倍左右;与此同时,如果采用同样工艺,CPU的封装将要扩大15倍;相应的,在同样的工艺下,电源供应的要求提升了将近18倍。 尽管这个例子显示的是Intel的状况,但我们会发现,任何一家高性能CPU的制造商,都面临着同样的困惑。

当然,我们上面假象的是制造工艺和技术都还停留在486的阶段,随着制造工艺的提高以及相关技术的不断突破,我们并没有看到上述的封包和电源需求的可怕状况,但CPU更新速度在加快,现有的制造工艺很快就会捉襟见肘,如果依然按照现有的性能提升发展下去,很快瓶颈就会出现,所以,必须寻找其他的道路来降低提升性能被工艺束缚的危险,超线程正是在这样一个背景下被Intel推向前台的。

二. 超线程的运行机理

超线程属于线程级并行的一种,其实现在软件发展的趋势尤其是在服务器软件方面正是向着多线程的方向发展,比如在在线事务处理和Web服务中,大量的线程由来自不同IP的不用请求产生,如果这些线程不能够并行处理, 那么整个网络服务器的性能将受到极大的影响;在桌面系统的软件中也存在着这种趋势,面对这样的一个情况,Intel清楚的看到,充分利用现有系统资源,优化并完善线程级的并行处理,使多个线程能够更好的同时处理,比不断的增加晶体管的数量来达到CPU性能的提升更有效。

现有的已经在中高端服务器/工作站领域充分利用的多处理器技术就可以被看作是线程级并行的一种,通过增加CPU的数目,系统的性能有了非常稳固的提升,将多个线程同时在多个处理器上同时运行,而不管它们是否来自一个程序。多处理技术目前已经是非常成熟的技术,但是它存在着成本的问题,无法进一步的在更主流的应用中普及。

近几年,更多的线程级并行解决方案被提出,基于他们的产品也有不少已经发布,在其中有几种典型的技术:

芯片级多进程:这种技术将两个完全一样的处理器封装在一起,它们都拥有独立的结构,共享大部分缓存资源,这种技术与传统的多处理器技术有着很大的区别, 因为你完全可以使用多个采用这种技术来构造的CPU组成一个多处理器系统,但是它的缺点也很明显,更大的封装尺寸以及昂贵的制造成本使其无法成为主流的处理器制造技术。

分时多进程:这种技术是让处理器在安排好的时序周期里交叉运行多个线程,这种技术在牺牲了频率性能的同时,以最小的代价节省了浪费的时序周期,但是对于那种需要大量内存读写操作的线程,它的影响有限。

事件响应多进程:这种技术是在一个线程需要进行长时间的后台处理比如对缓存进行读写操作的时候,将处理器的操作权交给另外一个线程,它应用于需要进行大量读写操作的服务器程序中对性能的提升很高。

并行多线程:无论是分时多进程还是事件响应多进程都有它无法避免的局限性,在它们的技术的基础上,并行多线程提出了新的解决思路,它在一个处理器内部实现了无需切换的多个线程并行处理,它能够更有效的利用处理器的资源,它是多种线程级并行方案中节约最多资源、提升性能最多并且适用范围最广的。

超线程就是并行多线程技术在Intel处理器架构中的体现,它在一个处理器的内部为每个逻辑处理器构建了一套架构状态(Architecture State以下简称AS),每个AS包括一个处理器必须的一些寄存器,包括:通用状态寄存器、控制寄存器、高级程序中断寄存器以及其他一些处理一个线程必须的寄存器, 完整的复制AS需增加的晶体管数量非常有限;同时两个逻辑处理器共享一套物理执行单元、分支预测单元、控制逻辑以及总线,从软件操作的角度来看,这意味着操作系统和应用程序可以象在一台多处理器的系统中运行一样来规划它的进程或者线程运行。而从微架构的角度来看,这意味着来自逻辑处理器的指令将在共享的运算单元并行处理。

不包含多线程技术的处理器的多处理器系统

作为一个例子,上图展示了一个典型的没有多线程技术支持的多处理器系统,下图展示了一个典型的采用多线程技术支持的CPU的多处理器系统,我们可以看到两个物理的处理器内部被分成了4个逻辑的处理器。

使用多线程技术处理器的多处理器系统

在超线程技术产品化的过程中,还有几个细节我们需要特别注意:

1. 尽量的缩小超线程技术对封包尺寸的影响:由于逻辑处理器共享了大部分的微结构资源而仅仅复制了一小部分必须的硬件资源,封包的尺寸仅仅增加了不到5%。

2. 当一个逻辑处理器停止运行的时候,另一个逻辑处理器应能够继续运行:一个逻辑处理器可能因为多种原因而暂时中断,比如等待缓存读写、等待上一条指令的结果等等,Intel通过一个中立的程序来管理指令缓冲队列,在有两个线程在进行的时候,它不允许任何一个逻辑处理器独占指令缓冲队列,这样就有效的避免了一个逻辑处理器独占指令缓冲队列并暂时中断时,另外一个逻辑处理器也陷入无限悲惨之漫长等待。

3. 当只有一个线程运行时资源的调配:当只有一个线程在处理器中运行的时候,拥有超线程技术的处理器的运行效率能否达到同档次没有超线程技术的处理器呢?这意味着当只有一个线程运行时,所有的资源都应该调配给它以便它能够更有效的运行,我们可以看到下面的图,在P4的超级流水线上,任何两个逻辑处理流程之间,都由缓冲队列来进行分割,通过这种方式,它保证了任何正在进行的线程能够根据缓冲队列的拥挤程度来请求资源并逐步完成线程,而当只有一个线程存在时,由于缓冲队列是空的,所以所有的资源都会提供给这个线程以保证它在最短时间完成操作。

要亲身感受Hyper-Threading超线程技术,除了带HT标志的P4外,以下的一些条件也是必不可少的,请看:

1、 采用含有HT技术的芯片组制造的主板。最新的Intel 845PE、845GE芯片组都支持HT技术;

2、 确保上述这类主板的BIOS中有开启HT技术的选项,并将其打开;

3、 为HT超线程技术进行优化的操作系统(Microsoft Windows XP家庭版或专业版,以及Linux 2.4.18或更新的版本)。需要注意的事,您原有的Ghost镜像文件已是无效的,必须在BIOS中打开HT后,重新安装操作系统,再进行Ghost备份的镜像文件才是支持HT超线程技术的;

4、 您的Microsoft Windows XP系统必须打好SP1补丁。

H. 架构高可用高并发系统的设计原则

通过学习《亿级流量网站架构核心技术》及《linux就该这么学》学习笔记及自己的感悟:架构设计之高可用高并发系统设计原则,架构设计包括墨菲定律、康威定律和二八定律三大定律,而系统设计包括高并发原则、高可用和业务设计原则等。
架构设计三大定律
墨菲定律 – 任何事没有表面看起来那么简单 – 所有的事都会比预计的时间长 – 可能出错的事情总会出错 – 担心某种事情发生,那么它就更有可能发生
康威定律 – 系统架构师公司组织架构的反映 – 按照业务闭环进行系统拆分/组织架构划分,实现闭环、高内聚、低耦合,减少沟通成本 – 如果沟通出现问题,应该考虑进行系统和组织架构的调整 – 适合时机进行系统拆分,不要一开始就吧系统、服务拆分拆的非常细,虽然闭环,但是每个人维护的系统多,维护成本高 – 微服务架构的理论基础 – 康威定律https://yq.aliyun.com/articles/8611– 每个架构师都应该研究下康威定律http://36kr.com/p/5042735.html
二八定律 – 80%的结果取决于20%的原因
系统设计遵循的原则
1.高并发原则
无状态
无状态应用,便于水平扩展
有状态配置可通过配置中心实现无状态
实践: Disconf、Yaconf、Zookpeer、Consul、Confd、Diamond、Xdiamond等
拆分
系统维度:按照系统功能、业务拆分,如购物车,结算,订单等
功能维度:对系统功能在做细粒度拆分
读写维度:根据读写比例特征拆分;读多,可考虑多级缓存;写多,可考虑分库分表
AOP维度: 根据访问特征,按照AOP进行拆分,比如商品详情页可分为CDN、页面渲染系统,CDN就是一个AOP系统
模块维度:对整体代码结构划分Web、Service、DAO
服务化
服务化演进: 进程内服务-单机远程服务-集群手动注册服务-自动注册和发现服务-服务的分组、隔离、路由-服务治理
考虑服务分组、隔离、限流、黑白名单、超时、重试机制、路由、故障补偿等
实践:利用Nginx、HaProxy、LVS等实现负载均衡,ZooKeeper、Consul等实现自动注册和发现服
消息队列
目的: 服务解耦(一对多消费)、异步处理、流量削峰缓冲等
大流量缓冲: 牺牲强一致性,保证最终一致性(案例:库存扣减,现在Redis中做扣减,记录扣减日志,通过后台进程将扣减日志应用到DB)
数据校对: 解决异步消息机制下消息丢失问题
数据异构
数据异构: 通过消息队列机制接收数据变更,原子化存储
数据闭环: 屏蔽多从数据来源,将数据异构存储,形成闭环
缓存银弹
用户层:
DNS缓存
浏览器DNS缓存
操作系统DNS缓存
本地DNS服务商缓存
DNS服务器缓存
客户端缓存
浏览器缓存(Expires、Cache-Control、Last-Modified、Etag)
App客户缓存(js/css/image…)
代理层:
CDN缓存(一般基于ATS、Varnish、Nginx、Squid等构建,边缘节点-二级节点-中心节点-源站)
接入层:
Opcache: 缓存php的Opcodes
Proxy_cache: 代理缓存,可以存储到/dev/shm或者SSD
FastCGI Cache
Nginx+Lua+Redis: 业务数据缓存
Nginx为例:
PHP为例:
应用层:
页面静态化
业务数据缓存(Redis/Memcached/本地文件等)
消息队列
数据层:
NoSQL: Redis、Memcache、SSDB等
MySQL: Innodb/MyISAM等Query Cache、Key Cache、Innodb Buffer Size等
系统层:
CPU : L1/L2/L3 Cache/NUMA
内存
磁盘:磁盘本身缓存、dirtyratio/dirtybackground_ratio、阵列卡本身缓存
并发化
2.高可用原则
降级
降级开关集中化管理:将开关配置信息推送到各个应用
可降级的多级读服务:如服务调用降级为只读本地缓存
开关前置化:如Nginx+lua(OpenResty)配置降级策略,引流流量;可基于此做灰度策略
业务降级:高并发下,保证核心功能,次要功能可由同步改为异步策略或屏蔽功能
限流
目的: 防止恶意请求攻击或超出系统峰值
实践:
恶意请求流量只访问到Cache
穿透后端应用的流量使用Nginx的limit处理
恶意IP使用Nginx Deny策略或者iptables拒绝
切流量
目的:屏蔽故障机器
实践:
DNS: 更改域名解析入口,如DNSPOD可以添加备用IP,正常IP故障时,会自主切换到备用地址;生效实践较慢
HttpDNS: 为了绕过运营商LocalDNS实现的精准流量调度
LVS/HaProxy/Nginx: 摘除故障节点
可回滚
发布版本失败时可随时快速回退到上一个稳定版本
3.业务设计原则
防重设计
幂等设计
流程定义
状态与状态机
后台系统操作可反馈
后台系统审批化
文档注释
备份
4.总结
先行规划和设计时有必要的,要对现有问题有方案,对未来有预案;欠下的技术债,迟早都是要还的。
本文作者为网易高级运维工程师

I. 商品详情页局部静态化实例分析以及技术点

流程简述:
1.商品后台进行商品导入,导入后发异步消息流生成局部静态模板页(图文详情介绍说明之类的----变化不大的内容)。

2.模板页的生成,可以利用ob缓存渲染html模板之类的,然后将模板文件上传到指定的服务器,这里对文件名的规则有一定的要求( https://image-shop.chuchujie.com/culiu.cdn/shop_staticHtml/detail/18/67/1100240643278_detail.html ),基于商品id进行hash运算得到的/18/67目录,所有调用端保持一致即可。

3.上传到七牛服务器需要注意的地方,七牛开启cdn加速,在多个地区开启多个节点,将文件上传到源站进行分发,除了源站外的其他地方直接访问的是cdn缓存,如果源站发生改变,需要主动提交刷新缓存请求或者通过携带随机 URL 参数刷新。这里使用通过携带随机 URL 参数刷新。

例如,如果 http://om9helk.qnssl.com/resource/gogopher.jpg 这个图片资源没有更新,可以在该 URL 后面加上问号随机参数的形式来让 CDN 强制刷新: http://om9helk.qnssl.com/resource/gogopher.jpg?v=1234567 ,CDN 拿到这个 URL 后会强制回源站中取回最新的资源。

如果域名没有开启忽略 URL 参数,那么在 CDN 节点上,对于:
( http://om9helk.qnssl.com/resource/gogopher.jpg )
( http://om9helk.qnssl.com/resource/gogopher.jpg?v=1 )
( http://om9helk.qnssl.com/resource/gogopher.jpg?v=2 )
这三个 URL 是独立缓存的。所以,如果携带之前没用过的参数访问,CDN 会强制回源站中取回最新的资源。

① 关闭忽略 URL 缓存的域名,才可以使用这种方法刷新。

本项目中采用nginx缓存一段时间的方法,来控制url的参数 https://image-shop.chuchujie.com/culiu.cdn/shop_staticHtml/detail/18/67/1100240643278_detail.html?v=15484108912&is_cct=0&is_oversea=0&delivery_type=0
参数v通过访问接口的时间戳来变化,来强制CDN更新。
还有一种好的方法是,更新模板的时候,主动提交刷新缓存请求,来使CDN更新所有缓存内容和源站同步。

4.然后是商品详情页接口,里面有需要的动态变化的数据,例如价格数量 sku,spu,活动时间以及优惠券等信息,也包含局部静态模板文件地址,ios/安卓可以拿到相应的地址开启web view进行展示,h5拿到地址进行get请求得到模板html,然后加载到商品详情页。

5.商品详情页接口里分多级缓存,这里使用memcache。然后使用nginx的fastcgi_cache缓存整个商品详情页接口,减少了nginx与php服务的请求,在高并发的情况下性能极佳。

6.这里需要注意的是更新商品内容时需要更新模板,以及nginx更新fastcgi_cache缓存的内容。(我的想法是,在知道更新了商品内容并且更新了模板后,则删除之前在nginx缓存该商品详情接口的内容,重新进行缓存,因为直接修改nginx的缓存比较困难,但是删除比较方便,直接根据规则删除对应的文件)

7.主要利用七牛上传文件,使用里面的刷新缓存功能来更新模板信息。
使其他的CDN缓存回源更新源站最新的内容然后进行缓存。

8.通过nginx配合lua,对特殊的fastcgi_cache缓存的内容进行实时修改数据,比如商品详情页里可能含有活动的倒计时时间,这个倒计时时间需要当前的服务时间与活动结束时间实时比较得到,这时候通过ngx.location.capture发起一个当前缓存页的请求,如果拿到的是缓存的数据,则将数据进行对应的修改local currentTime = os.time(),最后再response响应,ngx.say(response.body);
ngx.exit(ngx.HTTP_OK)。
当然一些无需变化的数据,直接走fastcgi_cache缓存的数据即可。

热点内容
酒店配置什么灭火系统 发布:2025-02-09 08:06:37 浏览:773
java至尊 发布:2025-02-09 08:03:23 浏览:558
pythonwith 发布:2025-02-09 08:00:25 浏览:172
Ftp打开文件是只读模式 发布:2025-02-09 07:40:55 浏览:504
androidlistview点击事件 发布:2025-02-09 07:25:52 浏览:171
targz解压缩 发布:2025-02-09 06:59:19 浏览:311
wpsphp 发布:2025-02-09 06:58:41 浏览:962
视易锋云系统如何架设辅助服务器 发布:2025-02-09 06:47:08 浏览:770
mysql备份脚本shell 发布:2025-02-09 06:46:33 浏览:15
腾讯云服务器怎样调整分辨率 发布:2025-02-09 06:46:30 浏览:369