php关于高并发的一些知识

时间:2022-10-30 17:28:51
<?php /**  * Created by PhpStorm.  * User: weisheng  * Date: 2018/3/26  * Time: 20:14  */  /*
 * 高并发和大流量解决方案考点
 * 1.高并发架构相关概念
 * 2.高并发解决方案
 */

/*
 * 高并发相关概念
 * 1.并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一时刻点上只有一个程序在处理机上运行。
 *  上面的定义明显不是我们通常所言的并发,在互联网时代,所讲的并发、高并发,通常是指并发访问。也就是在某个时间点,有多少个访问同时到来。
 * 2.高并发:通常如果一个系统的日PV在千万以上,有可能是一个高并发的系统。
 *
 * 高并发具体该关心啥?
 * 1.QPS:每秒钟请求或者查询的数量,在互联网领域,指每秒响应请求数(指HTTP请求)不等于并发连接数  并发连接数是系统同时处理的请求数量
 * 2.吞吐量:单位时间内处理的请求数量(通常由QPS与并发数觉定)
 * 3.响应时间:从请求发出到收到响应所花费的时间。例如系统处理一个HTTP请求需要100ms,这个100ms就是系统的响应时间
 * 4.PV:综合浏览量(Page View),即页面浏览量或者点击量,一个访客在24小时内访问页面的数量,同一个人浏览同一页面记一次PV
 * 5.UV:独立访客,即一定时间范围内相同访客多次访问网站,只计算为一个独立访客。
 * 6.带宽:计算带宽大小需关注两个指标,峰值流量和页面的平均大小
 * 7.日网站带宽=PV/统计时间(换算到秒)*平均页面大小(单位KB* 8
 *   (PV*80%/6小时秒数*20%=峰值每秒请求数(QPS)  //80%的访问量集中在20%的时间
 *
 * 压力测试:利用性能测试工具 如ab 测试目标是基于URL
 *
 * 流量优化:防盗链处理,将恶意请求排除在外
 * 前端优化:减少HTTP请求,添加异步请求,启用浏览器缓存和压缩,CDN加速,建立独立的图片服务器
 * 服务端优化:页面静态化,并发处理,队列处理
 * 数据库优化:数据库缓存,分库分表、分区操作,读写分离
 * web服务器优化:负载均衡
 */

/*
 * web资源防盗链
 *
 * 盗链:指在自己的页面上展示一些并不在自己服务器上的内容,获得他人服务器上的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容
 *
 * 防盗链:防止别人通过一些技术手段绕过本站的资源展示页面,盗用本站的资源,让绕开本站资源展示页面的资源链接失效
 * 工作原理:通过Referer(请求来源)或者签名,网站可以检测到目标网页访问的来源网页,如果是资源文件,则可以追踪到显示它的网页地址。一旦检测到来源不是本站即进行阻止或者返回指定页面
 *
 * 防盗链的实现:
 * RefererNginx模块 ngx_http_referer_module用于阻挡来源非法的域名请求
 *          Nginx指令valid_referers,全局变量$invalid_referer
 *          valid_referers none|blocked|server_name|string...;
 *          none:"Referer"来源头部为空的情况(合法)
 *          blocked:"Referer"来源头部不为空,但是里面的只被代理或者防火墙删除了,这些值都不以http://或者https://开头
 *          server_name:来源referer包含server_name(允许源)
 * 使用加密签名:使用点三方模块HttpAccessKeyModule实现Nginx防盗链
 *             accesskey on|off模块开关
 *             accesskey_hashmethod md5|sha_1签名加密方式
 *             accesskey_arg GET参数名称
 *             accesskey_signature 加密规则
 *
 */

/*
 * 减少HTTP请求
 *      HTTP连接产生的开销 解析花费时间
 *      合并图片(图片地图,css精灵),js,css
 *      图片使用Base64编码减少页面请求数:采用用Base64编码方式将图片直接嵌入到网页中,而不是从外部导入
 */

/*
 * 浏览器缓存和数据压缩
 *
 * 缓存分类:
 * HTTP缓存模型中,如果请求成功会有三种情况
 * 200 from cache:直接从本地缓存中获取响应,最快速,最省流量,因为根本没有向服务器发送请求
 * 304 Not Modified:协商缓存,浏览器在本地没有命中的情况下请求头中发送一定的检验数据到服务器端,如果服务器端数据没有改变,浏览器从本地缓存响应,返回304     快速,发送的数据很少,只返回一些基本的响应头信息,数据很小,不发送实际响应体
 * 200 OK:以上两种缓存都失败,服务器返回完整响应。没有用到缓存,相对最慢
 *
 * 本地缓存:如果浏览器认为本地缓存可以用,就不需要去请求服务器
 * 相关Header
 * Pragma:HTTP1.0时代的遗留产物,该字段被设置为no-cache时,会告知浏览器禁用本地缓存,即每次都向服务器发送请求
 * ExpiresHTTP1.0时代用来启用本地缓存的字段,expires值对应一个形如Thu,31 Dec 2037 23:55:55 GMT 的格林威治时间,告诉浏览器缓存实现的时刻,如果还没到该时刻,标明缓存有效,无需发送请求。浏览器与服务器的时间无法保持一致,时间相差太大会影响缓存
 * Cache-Control:HTTP1.1针对Expires时间不一致的解决方案,运用Cache-Control告知浏览器缓存过期的时间而不是时刻,及时具体时间不一致,也不影响缓存的管理
 *              no-store:禁止浏览器缓存响应
 *              no-cache:不允许直接使用本地缓存,先发起请求和服务器协商
 *              max-age=data-seconds:告知浏览器该响应本地缓存有效地最长期限,以秒为单位
 *
 * 优先级:Pragma>Cache-Control>Expires
 *
 * Last-Modified:通知浏览器资源的最后修改时间
 * If-Modified-Since:得到资源的最后修改时间后,会将这个信息通过If-Modified-Since提交到服务器做检查,如果没有修改,返回304状态码
 * ETag:HTTP1.1推出,文件的指纹标识符,如果文件内容修改,指纹会改变
 * If-None-Match:本地缓存失效,会携带此值去请求服务器,服务端判断该资源是否改变,如果没有改变,直接使用本地缓存,返回304
 *
 *
 *
 * 缓存策略的选择:
 * 不变的图像,如logo,图标等 jscss静态文件 可下载内容,媒体文件
 * 建议使用协商缓存:HTML文件,经常修改的图片、jscss文件
 * 不建议缓存的内容:用户的隐私内容以及经常修改的api数据接口
 *
 * 本地缓存配置:add_header指令:添加状态码为2XX3XX的响应头信息
 *             add_header name value [always];
 *             可以设置Pragma/Expires/Cache-Control,可以继承
 *          expires指令:通知浏览器过期时长
 *          expires time 为负值时 表示no cache max时为10
 *
 * 协商缓存: Etag指令
 *
 * 前端代码和资源的压缩:图片压缩、jscss等压缩
 *
 */
//$since=$_SERVER['HTTP_IF_MODIFIED_SINCE'];
//$lifetime=10;
//if(strtotime($since)+$lifetime>time()){
//
//    header('HTTP/1.1 304 Not Modified');
//    exit;
//}
//header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()). ' GMT');
//
//echo time();


/*
 * CDN加速
 * 什么是CDNCDN的全称是Content Delivery Network,即内容分发网络
 * 在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络
 * CDN系统能够实时地根据网络流量和各节点的连接,负载状况以及到各用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务器节点上
 *
 * 使用CDN的优势:本地Cache加速,提高了企业站点(尤其含有大量图片和静态页面站点)的访问速度
 *              跨运营商的网络加速,保证不同网络的用户都得到良好的访问质量
 *              远程访问用户根据DNS负载均衡技术智能自动选择Cache服务器
 *              自动生成服务器的远程Mirror(镜像)cache服务器,远程用户访问时从cache服务器上读取数据,减少远程访问的带宽,分担网络流量,减轻原站点WEB服务器负载等功能
 *              广泛分布的CDN节点加上节点之间的智能冗余机制,可以有效地预防黑客入侵
 *
 *
 * CDN的工作原理:
 * 传统访问:用户在浏览器输入域名发起请求-->解析域名获取服务器IP地址-->根据IP地址找到对应的服务器-->服务器响应并返回数据
 * 使用CDN访问:用户发起请求-->智能DNS的解析(根据IP判断地理位置、接入网络型、选择路由最短和服务器最轻的服务器)-->取得缓存服务器IP-->把内容返回给用户(如果缓存中有)-->向源站发起请求-->将结果返回给用户-->将结果存入缓存服务器
 *
 * 应用场景:站点或者应用中有大量的静态资源
 *         大文件下载
 *         直播网站
 *
 * 实现:BAT等都有提供CDN服务
 *      可用LVS4层负载均衡
 *      可以使用apache noginx
 *      使用squid反向代理,或者Nginx等的反向代理
 *
 */

/*
 * 独立图片服务器的部署
 *
 * 独立的必要性:分担Web副武器的I/O负载-将耗资源的图片服务分离出来,提高服务期的性能和稳定性
 *            能够专门对服务器进行优化-为图片服务设置有针对性的缓存方案,减少带宽成本,提高访问速度
 *            提高网站的可扩展性-通过增加图片服务器,增加图片的吞吐
 *
 * 采用独立域名:同一浏览器下并发连接数有限制,突破浏览器连接数的限制
 *             由于cookie,对缓存不利,大部分Web cache都只缓存不带cookie的请求,导致每次图片请求都不能命中cache
 *
 * 独立后的问题:
 * 如何进行图片上传和图片同步:
 * NFS共享方式
 * 利用FTP同步
 */

/*
 * 动态语言静态化
 *
 * 什么是动态语言静态化:将现有PHP等动态语言的逻辑代码生成为静态HTML文件,用户访问动态脚本重定向到静态HTML文件的过程 不高的页面
 *
 * 为什么要静态化:
 * 原因:1.动态脚本通常会做逻辑运算和数据查询,访问量越大,服务器压力越大
 *      2.访问量大时可能会造成CPU负载过高,数据库服务器压力过大
 *      3.静态化可以减低逻辑处理压力,降低数据库服务器查询压力
 *
 * 静态化的实现方式:
 * 使用模板引擎:可以使用Smarty的缓存机制生成静态的HTML缓存文件
 * 利用ob系列的函数:ob
 */

/*
 * 动态语言并发处理
 *
 * 进程:进程是计算机中的程序关于某数据集合上的的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础 进程是一个执行中的程序 *  进程的三态模型:多道程序系统中,进程在处理器上交替运行,状态不断地发生变化
 *              运行、就绪、阻塞
 * 线程:线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指令运行时的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
 *       运行、就绪、阻塞
 * 协程:协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。
一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

 *
 *线程与进程之间的区别:
 * 1.线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有自己独立的空间地址
 * 2.进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
 * 3.线程是处理器调度的基本单位,但进程不是
 * 4.二者都可以并发执行
 * 5.每个独立的线程有一个程序的入口,顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
 *
 * 线程与协程的区别:
 * 1.一个线程可以有多个协程,一个进程也可以单独有多个协程
 * 2.线程是同步机制,而协程则是异步
 * 3.协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次的调用状态
 *
 * 多进程与多线程
 * 多进程:同一个计算机在同一时间允许系统中两个个或两个以上的进程处于运行状态,这就是多进程
 * 多线程:线程就是把一个进程分为多个片段,每个进程占据一个独立的片段
 *
 *
 * php并发编程实践:
 * SwooleSwoole 使用纯 C 语言编写,提供了 PHP 语言的异步多线程服务器,异步 TCP/UDP 网络客户端,异步 MySQL,异步 Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。 Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。
除了异步 IO 的支持之外,Swoole  PHP 多进程的模式设计了多个并发数据结构和IPC通信机制,可以大大简化多进程并发编程的工作。其中包括了并发原子计数器,并发 HashTableChannelLock,进程间通信IPC等丰富的功能特性。
Swoole2.0 支持了类似 Go 语言的协程,可以使用完全同步的代码实现异步程序。PHP 代码无需额外增加任何关键词,底层自动进行协程调度,实现异步。

 */

/*
 * 数据库缓存
 *
 * 什么是数据库缓存:MySQL等一些常见的关系数据库的数据存储在磁盘中,在高并发场景下,业务应用对MySQL产生的增、删、改、查的操作造成巨大的I/O开销和查询压力,这无疑对数据库和服务器都是一种巨大的压力,为了解决此类问题,缓存数据库应运而生
 * 为什么要使用缓存:缓存数据是为了减少客户端访问数据库服务器进行数据查询
 *
 * MySQL查询缓存:query_cache_type
 *
 * 使用Memcache缓存查询数据:
 * memcache:分布式的高速缓存系统
 * 工作原理:
 * 工作流程:
 *
 * 使用Redis缓存:
 * Redis:
 * 工作原理:
 * 工作流程:
 *
 * RedisMemcache
 * 性能相差不大
 * Redis2.0版本后增加了自己的VM特性,突破物理内存限制,Memcache可以修改最大可用内存,采用LRU算法
 * Redis,依赖客户端来实现分布式读写
 * Memcache本身没有数据冗余机制
 * Redis支持(快照、AOF),依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响
 *
 */


/*
 * 七层负载均衡:基于URL等应用层信息
 */