PHP 如何办理网站大流量与高并发的问题(一壁末了一题)

变体:

网站高并发的优化方法,从浏览器到做事器中间经由所有组件的你能想到的优化点(二面末了一题)

李捷php从一道百度面试题说起 Docker

考点剖析高并发架构干系观点高并发办理方案(优化方案)解释

由于涉及到的知识点太多,我这里先给出我当时回答的总的构造,之后会对每个分点进行更为详细的剖析,如果你有更好的答案,或者有一些遗漏的点还请指出。

高并发架构干系观点

并发(百度百科的定义):

并发,在操作系统中,是指一个韶光段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一处理机上运行,但任意时候点上都只有一个程序在处理机上运行

web开拓中说的高并发指的是什么?

上面的定义明显不是我们常日所言的并发,在互联网时期,所讲的并发、高并发,常日是指并发访问。
也便是在某个韶光点,有多少个访问同时到来,常日如果一个别系的日 PV 在干万以上,有可能是一个高并发的系统。

高并发的问题,我们详细该关心什么?

QPS:

每秒钟要求或者査询的数量,在互联网领域,指毎秒相应要求数(指 HTTP 要求),一个页面中可能有多个 HTTP 要求。

吞吐量:

单位韶光内处理的要求数量(常日由QPS与并发数决定)

相应韶光:

从要求发出到收到相应花费的韶光。
例如系统处理一个 HTTP 要求须要 100ms,这个 100ms 便是系统的相应韶光

PV:

综合浏览量(Pageview),即页面浏览量或者点击量

UV:

独立访客(UniqueVisitor),即一定韶光范围内相同访客多次访问网站,只打算为 1 个独立访客

带宽:

打算带宽大小需关注两个指标,峰值流量和页面的均匀大小

日网站带宽 = PV/统计韶光(换算到秒) 均匀页面大小(单位 KB) 8

常用的压测工具

ApacheBench、WRK、http_load、Web bench、Siege、Apache Jmeter

ApacheBench 观点

ApacheBench(ab),是 Apache 官方推出的工具刨建多个并发访问线程,仿照多个访问者同时对某一 URL 地址进行访问。
它的测试目标是基于 URL 的,因此,它既可以用来测试 Apache 的负载压力,也可以测试 Nginx、 Lighttpd、 Tomcat、IS 等其它 Web 做事器的压力。

ApacheBench 的利用

仿照并发要求 1000次,统共要求 50000次

ab -c 1000 -n 50000 www.test.com

把稳事变

测试机器与被测试机器分开不要对线上做事做压力测试不雅观察测试工具 ab 所在机器,以及被测试的前端机的 CPU,内存,网络等都不超过最高限度的 75% (top 命令)

高并发办理方案(优化方案)

流量层优化:

防盗链处理

前端层优化:

减少 HTTP 要求添加异步要求启用浏览器缓存和文件压缩CDN 加速建立独立图片做事器

做事器层优化:

页面静态化并发处理

数据库层优化:

数据库缓存(Memache, Redis)分库分表(水平、垂直切分)、分区操作读写分离负载均衡

Web 做事器架构优化:

负载均衡流量层优化(防盗链处理)

如果我们创造我们的网站主页的流量很大(做事器负荷很重)但是网站的 PV、UV 却很小,这时候我们就须要考虑我们的网站是不是被盗链了。

盗链观点

盗链是指在自己的页面上展示一些并不在自己做事器上的内容得到他人做事器上的资源地址,绕过别人的资源展示页面,直接在自己的页面上向终极用户供应此内容,常见的是小站盗用大站的图片、音乐、视频、软件等资源,通过盗链的方法可以减轻自己做事器的包袱,由于真实的空间和流量均是来自别人的做事器。

防盗链观点

防止别人通过一些技能手段绕过本站的资源展示页面,盗用本站的资源,让绕开本站资源展示页面的资源链接失落效,可以大大减轻做事器及带宽的压力。

事情事理

通过 Referer 或者署名,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。
一旦检测到来源不是本站即进行阻挡或者返回指定的页面。

Referer 办法防盗链

Nginx 模块 ngx_http_referer_module 用于阻挡来源造孽的域名要求。

配置

location ~ .\.(gifljpglpnglflvlswfrarlzips)${

valid_referers none blocked test.com test.com:

if($invalid_referer){

#return 403:

rewrite ^/ http://www.test.com/403.jpg;

}

}

valid_referers none I blocked I server_names,string

阐明

none: \公众Referer\公众 来源头部为空的情形blocked: \公众Referer\"大众 来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以 http:// 或者 https:// 开头。
server names: \"大众Referer\公众 来源头部包含当前的 server names

加密署名防盗链

Referer 这种办法虽然可以防止一下低中级的防盗链,但是更高等的盗链每每可以假造 Referer,从而绕过 Referer 检测,更安全的办法是可以采取加密署名办理 。

利用第三方模块 HttpaccesskeyModule 实现 Nginx 防盗链

Nginx 配置:

accesskey on off 模块开关

accesskey_hashmethod md5 | sha-1 署名加密办法

accesskey_arg GET 参数名称

accesskey signature 加密规则

location ~ .\.(gifljpglpnglflvlswfrarlzips)${

accesskey on;

accesskey_hashmethod md5;

accesskey_arg sign;

accesskey_signature\公众yourPrefix$remote_addr; # 你的前缀码和客户端 IP

}

PHP 代码段:

$sign= md5('yourPrefix'. $_SERVER['remote_addr'];

echo '<img src=”./youimage.png?sign=. $sign.'\公众>';

前端层优化

减少 HTTP 要求

性能黄金法则:

只有 10% - 20% 的终极用户相应韶光花在吸收要求的 HTML 文档上,剩下的 80% - 90% 韶光花在 HTML 文档所引用的所有组件(图片,脚本,CSS,Flash 等等)进行的 HTTP 要求上。

如何改进:

改进相应韶光的最大略路子便是减少组件数量,并由此减少 HTTP 要求的数量。

减少 HTTP 要求的办法

图片舆图

图片地址许可你在一个图片上关联多个 URL,目标 URL 的选择取决于用户单击了图片上的哪个未知。

将五张图片合并为一张图片,然后以位置信息定位超链接,把五个 HTTP 要求减少为一个,可以担保设计的完全性和功能的完好性利用 标签

CSS 精灵(CSS Sprites)

Sprites 中文翻译为 CSS 精灵,通过利用合并图片,通过指定 CSS 的 background-image 和 background-position 来显示元素。

合并脚本和样式表

利用外部的 JS 和 CSS 文件引用的办法,由于这要比直接写在页面中性能更好一点独立的一个 JS 比用多个 JS 文件组成的页面载入要快 38%把多个脚本合并为一个脚本,把多个样式表合并为一个样式表

图片利用 Base64 编码减少页面要求数

采取 Base64 的编码办法将图片直接嵌入到网页中,而不是从外部载入。

添加异步要求

Ajax 可以实现动态不刷新(局部刷新),便是能在不更新全体页面的条件下掩护数据。
这使得 Web 运用程序更为迅捷地回运用户动作,并避免了在网络上发送那些没有改变过的信息。

上风:

通过异步模式,提升了用户体验优化了浏览器和做事器之间的传输,减少不必要的数据来回,减少了带宽占用Ajax 引擎在客户端运行,承担了一部分本来由做事器承担的事情,从而减少了大用户量下的做事器负载

启用浏览器缓存和文件压缩

缓存分类:

HTTP 缓存模型中,如果要求成功会有三种请款

200 from cache:直接从本地缓存中获取相应,最快速,最省流量,由于根本没有向做事器发送要求304 Not Modified:协商缓存,浏览器再本地没有命中的情形下要求头中发送一定的校验数据到做事端,如果做事端数据没有改变浏览器从本地缓存相应,返回304,快速,发送的数据很少。
只返回一些基本的相应头信息,数据量很小,不发送实际相应体200 OK:以上两种缓存全部失落败,做事器返回完全相应,没有用到缓存,相对最慢

本地缓存

浏览器认为本地缓存可以利用,不会去要求做事端

干系 Header:

Expires:expires 值对应一个形如 Thu,32 Dec 2037 23:55:55 GMT 的格林威治韶光,见告浏览器缓存实现的时候,如果还没到该时候,标明缓存有效,无需发送要求(绝对韶光)Cache-Control(设置缓存秒数):利用 Cache-Control 奉告浏览器缓存过期的韶光间隔不是时候(韶光间隔)no-store:禁止浏览器缓存相应no-cache:不许可直策应用本地缓存,先发起要乞降做事器协商max-age=delta-seconds:奉告浏览器该相应本地缓存有效的最长期限,以秒为单位

协商缓存

当浏览器没有命中本地缓存,如本地缓存过期或者相应中声明不许可直策应用本地缓存,那么浏览器肯定会发起做事端要求,做事端会验证数据是否修正,如果没有关照浏览器利用本地缓存

干系 Header:

Last-Modified:关照浏览器资源的末了修正韶光If-Modified-Since:得到资源的末了修正韶光后,会将这个信息通过 If-Modified-Sinc 提交到做事器做检讨,如果没有修正,返回 304 状态码Etag:HTTP1.1 推出,文件的指纹标识符,如果文件内容修正,指纹会改变If-None-Match:本地缓存失落效,会携带此值去要求做事端,做事端判断该资源是否改变,如果没有改变,直策应用本地缓存,返回 304

适宜缓存的内容

不变的图像,如 logo,图标等JS、CSS 静态文件可下载的内容,媒体文件

建议利用协商缓存

HTML 文件常常更换的图片常常修正的 JS、CSS 文件JS、CSS 文件的加载可以加入文件的署名来谢绝缓存index.css? 署名

不建议缓存的内容

用户隐私等敏感数据常常改变的 API 数据接口

前端代码和资源的压缩

上风:

让资源文件更小,加快文件再网络中的传输,让网页更快的展现,降落带宽和流量开销

压缩办法:

JS、CSS、图片、HTML 代码的压缩、Gzip 压缩

JavaScript 代码压缩:

JavaScript 压缩的事理一样平常是去掉多余的空格和回车、更换长变量名、简化一些代码写法等JavaScript 代码压缩工具很多,有在线工具,有运用程序,有编辑器插件

CSS 代码压缩:

事理跟 JavaScript 压缩事理类似,同样是去除空缺符、注释并且优化一些 CSS 语义规则等

利用 CDN 加速

CDN 的全称是 Content Delivery Network, 即内容分发网络,尽可能避开互联网上有可能影响数据传输速率和稳定性的瓶颈和环节,使内容传输的更快,更稳定。

在网络各处放置节点做事器所构成的在现有的互联网根本之上的一层智能虚拟网络CDN 系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的间隔和相应实践等综合信息将用户的要求重新导向离用户最近的做事器节点上。

利用 CDN 的上风

本地 cache 加速, 提高企业站点(尤其含有大量图片和静态页面站点)的访问速率跨运营商的网络加速, 担保不同网络的用户都得到良好的访问质量远程访问用户根据 DNS 负载均衡技能智能自动选择 cache 做事器自动天生做事器的远程 Mirror(镜像)cache 做事器,远程用户访问时从 cache 做事器上读取数据,减少远程访问的带宽、分担网络流量、减轻原站点 Web 做事器负载等功能。

建立独立的图片做事器

好处

分担 Web 做事器的 I/O 负载将耗费资源的图片做事分离出来,提高做事器的性能和稳定性能够专门对图片做事器进行优化-为图片做事设置有针对性的缓存方案,减少带宽本钱,提高访问速率提高网站的可扩展性-通过增加图片做事器,提高图片吞吐能力做事器层优化

页面静态化(动态措辞静态化)

将现有 PHP、Python 等动态措辞的逻辑代码天生为静态 HTML 文件,用户访问动态脚本重定向到静态 HTML 文件的过程

利用场景

对实时性哀求不高的页面

好处

动态脚本常日会做逻辑打算和数据查询,访问量越大,做事器压力越大访问量大时可能会造成 CPU 负载过高,数据库做事器压力过大

PHP 的并发处理

PHP 的 Swoole 扩展

PHP 的异步、并行、高性能网络通信引擎,利用纯 C 措辞编写,供应了 PHP 措辞的异步多线程做事器,异步 TCP/UDP 网络客户端,异步 MYSQL,异步 Redis,数据库连接池,Asynctask,行列步队,毫秒定时器,异步文件读写,异步 DNS 查询,除了异步 I/O 的支持之外, Swoole 为 PHP 多进程的模式设计了多个并发数据构造和 IPC 通信机制,可以大大简化多进程并发编程的事情。

行列步队

利用场景

用户注册:

场景解释用户注册后,须要发注册邮件和注册短信串行办法将注册信息写入数据库成功后,发送注册邮件,再发送注册短信并行办法将注册信息写入数据库成功后,发送注册郎件的同时发送注册短信行列步队办法将注册信息写入数据库成功后,将成功信息写入行列步队,此时直接返回成功给用户,写入行列步队的韶光非常短,可以忽略不计,然后异步发送邮件和短信

日志处理:

运用处景办理大量日志的传输,日志采集程序将程序写入行列步队,然后通过日志处理程序的订阅消费日志

常见行列步队产品

Kafka、 Activemq、 Zeros、 Rabbitmq、 Redis 等

数据库层优化

数据库缓存(Memache, Redis)

MySQL 等一些常见的关系型数据库的数据都存储在磁盘当中,在高并发场景下,业务运用对 MySQL 产生的增、删、改、查的操作造成巨大的 I/O 开销和查询压力,这无疑对数据库和做事器都是一种巨大的压力,为理解决此类问题,缓存数据的观点应运而生。

优点:

极大地办理数据库做事器的压力提高运用数据的相应速率

利用 Memcache 缓存查询数据

对付大型站点,如果没有中间缓存层,当流量打入数据库层时,即便有之前的几层为我们挡住一部分流量,但是在大并发的情形下,还是会有大量要求涌入数据库层,这样对付数据库做事器的压力冲击很大,相应速率也会低落,因此添加中间缓存层很有必要。

事情事理

Memcache 是一个高性能的分布式的内存工具缓存系统,通过在内存里掩护一个统一的巨大的 hash 表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
大略的说便是将数据调用到内存,然后从内存中读取,从而大大提高读取速率

利用 Redis 绶存查询数据

Memcache 的差异:

Redis 支持(快照、AOF),依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响Memcache 不支持持久化,常日做缓存,提升性能Redis 支持多种类的数据类型Redis 用于数据量较小的高性能操作和运算上Memcache 用于在动态系统中减少数据库负载,提升性能,适宜做缓存,提高性能

数据表数据类型优化

tinyint (0-255) smallint, bigint(考虑空间的问题,考虑范围的问题)char,vacharenum 特定、固定的分类可以利用 enum 存储,效率更快IP 地址的存储,用 PHP 的 ip2long('192.168.1.38'); //3232235814

索引优化

索引不是越多越好,在得当的字段上创建得当的索引复合索引的前缀原则lke 查询 % 的问题(% 在前如:%name 则索引失落败)全表扫描优化(MySQL 自动识别)or 条件索引利用情形(or 后的索引不会利用)字符串类型索引失落效的问题(如字符串类型的字段必须要加引号查询)

SQL 语句的优化

利用慢查询日志找到须要优化的 SQL 语句,一样平常会再用 explain 剖析。

优化查询过程中的数据访问利用 Limit返回列不用 优化特定类型的查询语句优化关联查询优化子查询优化 Group by 和 distinct

数据库做事器架构的优化

分库分表水平切分垂直切分读写分离负载均衡通过 LVS 的三种基本模式实现负载均衡My Cat 数据库中间件实现负载均衡Web 做事器架构优化

七层负载均衡的实现

基于 URL 等运用层信息的负载均衡Nginx 的 proxy 是它一个很强大的功能,实现了7层负载均衡

Nginx 的大略配置

Nginx 配置

http{

upstream test_cluster {

server 121.41.68.2:8001 weight=11;// 加权中

server 121.41.69.2:8002 weight=10;

#server 121.41.68.2:8003;

#server 121.41.68.9;

}

server {

listen 80;

location / {

proxy_pass http: //test_cluster;

}

}

}

四层负载均衡的实现

通过报文中的目标地址和端口,再加上负载均衡设备设置的做事器选择办法,决定终极选择的内部做事器LVS 实现做事器集群负载均衡有三种办法,NAT,DR 和 TUN

参考资料

AJAX 笔试口试题汇总李捷的全面解读 PHP 口试