怎么解决高并发大流量问题?下面本篇文章就来给你们分享下高并发大流量web解决思路及方案,但愿对你们有所帮助!php
高并发web架构相关概念
-
QPS:每秒钟请求或查询的数量,在互联网领域,指每秒相应请求数(http请求)。css
-
峰值每秒的QPS:(总PV数80%)/(6小时秒数20%),80%的访问量集中在20%的时间html
-
并发链接数:系统同时处理的请求数量前端
-
吞吐量:单位时间内处理的请求数量(一般由QPS与并发数决定)。mysql
-
响应时间:从请求发出到收到响应花费的时间。例如系统处理一个HTTP请求须要100ms,这个100ms就是系统的响应时间。react
-
PV:综合浏览量(Page View)即页面浏览量和点击量,一个访客在24小时内访问的页面数量。nginx
-
UV:独立访客(UniQue Visitor),即必定时间范围内相同访客屡次访问网站,只计算为1个独立访客。git
-
带宽:计算带宽大小关注两个指标,峰值流量和平均页面大小。github
-
日网站带宽=PV/统计时间(一天换算到秒)*平均页面大小(单位KB)*8。web
-
压力测试:测试承受的最大并发,测试最大承受的QPS,须要注意的测试并发测试机须要与被测试机器分开,不要对线上服务器进行并发测试,观察ab测试的所在机器,以及被测试机器的前端机的CPU,内存,网络等都不超过最高限度的75%。
-
并发量
-
响应速度
-
容错能力
-
-
经常使用的性能测试工具:ab,wrk,http_load,Web Bench,Siege,Apache JMeter。
高并发大流量web总体解决思路
-
流量优化
-
web资源防盗链防止第三方系统盗用图片,css,js等占用服务器流量和服务器带宽
-
前端优化
-
减小http请求:图片合并,js合并,css合并压缩,虽然文件可能大点但请求会减小
-
添加异步请求:经过实际ajax调用接口获取数据
-
启动浏览器的缓存和文件压缩(也能够启用nginx的压缩模块)
-
cdn加速:解决带宽不够用的问题,数据缓存到cdn的节点,访问的时候选择就近的节点,减小带宽加快访问速度
-
创建独立的图片服务器:图片是很吃io的,能够将图片服务器与web服务器彻底分离开,能够区分其它服务器单独搭建图片服务器不属于计算型的配置能够适当的调整,图片服务器还能够集群
-
服务端的优化
-
页面的静态化:动态的页面静态html,减小服务器的负载压力,页面静态化穿透,静态化有有效时间
-
动态语言并发处理:异步处理,多线程,队列的异步处理
-
-
数据库的优化:
-
数据库的缓存:memcache,redis的缓存
-
mysql索引优化,mysql分库分表,mysql分区操做,mysql主从复制读写分离,mysql的负载均衡,mysql的主从热备
-
web服务器的优化:
-
负载均衡:可使用ningx的反向代理使用负载均衡,可使用网络分层中的第四层lvs实现负载均衡
web服务器负载均衡
负债均衡
-
四层负载均衡:所谓四层负载均衡就是基于IP+端口的负载均衡
-
七层负载均衡:所谓七层的负载均衡就是基于(URL)信息的负载均衡
七层负载均衡实现:
基于URL等应用层信息的负债均衡 ningx的proxy是它一个很强大的功能,实现了7层负载均衡,功能强大,性能卓越,运行稳定,配置简单灵活,可以自动剔除工做不正常的后端服务器,上传文件可使用异步模式上传,支持多种分配策略,能够分配权重,分配方式灵活。
nginx负载均衡策略
-
IP Hash(内置)
-
加权轮询(内置)
-
fair策略(扩展)
-
通用hash(扩展)
-
一致性hash(扩展)
一、IP Hash策略
nginx内置的另外一个负载均衡的策略,流程和轮询很类似,只是其中的算法和具体的策略有些变化,IP hash算法是一种变相的轮询算法
二、加权轮训策略
首先将请求都分给高权重的机器,直到该机器的权值降到了比其余机器低,才开始将请求分给下一个高权重的机器,当全部后端机器都down掉时,nginx会当即将全部机器的标志位清成初始状态,以免形成全部的机器都处在timeout的状态
三、fair策略
根据后端服务器的响应时间判断负载状况,从中选出负载最轻的机器进行分流
通用hash、一致性hash策略,通用hash比较简单,能够以nginx内置的变量为key进行hash,一致性hash采用了内置的一致性hash环,支持memcache
四层负载均衡实现
经过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器
lvs相关术语:
-
DS:director server 目标服务器,即负载均衡器
-
RS:Real Server 真实服务器,即后端服务器
-
VIP:直接面向用户的IP地址,一般为公网IP地址
-
DIP:Director Server Ip主要用于内部主机通讯的IP地址
-
RIP:Real Server IP 后端真实服务器的IP地址
-
CIP:Client IP
lvs负载均衡三种方式:
NAT:修改目标IP地址为后端的RealServer的IP地址
DR:修改目标mac地址为后端的RealServer的mac地址
TUNNEL:较少使用,经常使用于异地容灾
四七层负载均衡优缺点
四层比七层能够承载更大的并发量,使用大型站点小
七层能够实现更为复杂的负载均衡控制,好比URL、基于session、动静分离等
七层可以占用大量的CPU时间,承载的并发量
cdn加速
什么是cdn?
节点:能够理解为真实服务器的镜像。
全称是Content Delivery Network,即内容分发网络尽量避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。
在网络各处放置节点服务器所构成的现有的互联网基础之上的一层智能虚拟网络。
cdn系统可以实时地根据网络流量和各节点的链接,负载情况以及到用户的距离和响应时间等综合信息将用户的请求从新导向离用户最近的服务节点上。
cdn的优点是什么?
-
一、本地的cache加速,提升企业站点(尤为含有大量图片和静态页面站点)的访问速度
-
二、跨运营商的网络加速,保证不一样网络的用户获得良好的访问质量
-
三、远程访问用户根据DNS负载均衡技术智能自动选择Cache服务器
-
四、自动生成服务器的远程Mirror(镜像)cache服务器,远程用户访问时从cache服务器上读取数据,减小远程访问的带宽,分担网络流量,减轻愿站点web服务器负载等功能。
-
五、普遍分布的cdn节点加上节点之间的智能冗余机制,能够有效的预防黑客入侵
cdn的工做原理是什么?
传统的访问:用户在浏览器输入域名发起请求,解析域名获取服务器ip地址,根据ip地址找到对应的服务器,服务器响应并返回数据。
使用cdn访问:用户发起请求,智能dns的解析(根据ip判断地理位置,接入网类型,选择路由最短和负载最轻的服务器),取得缓存服务器ip,把内容返回给用户(若是缓存中有),向源站发起请求,将结果访问给用户,将结果存入缓存服务器。
cdn的适用场景?
站点或者应用中大量静态资源的加速分发,例如:css,js,图片和html
cdn的实现方式?
-
BAT等实现的CDN服务
-
使用LVS的4层负载均衡
-
可用nginx,varnish,squid,apache trafficServer作七层负载均衡和cache 使用squid作反向代理或者nginx作反向代理
创建独立的图片服务器
独立的必要性?
-
一、分担web服务器的I/O负载,将耗费资源的图片服务分离出来,提升服务器的性能和稳定性
-
二、可以专门对图片服务器进行优化,为图片服务设置针对性的缓存方案,减小带宽成本,提升访问速度
为啥采用独立的域名?
缘由:同一域名下浏览器的并发链接数是有限制的,突破浏览器链接的限制,因为cookie的缘由,对缓存不利,大部分web cache都只缓存不带cookie的请求,致使每次的图片请求都不可以命中cache
独立后的问题?
-
如何进行图片上传和图片同步
-
NPS共享方式
-
利用FTP同步
动态页面静态化
相关概念:什么是动态语言静态化,为何要静态化,静态化的实现方式。
动态语言的并发处理
什么是进程
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操做系统结构的基础
进程是一个“执行中的程序”
进程的状态的三态模型
多道程序系统中,进程在处理器上交替运行,状态不断发生变化。
-
运行:当一个进程在处理机上运行时,则称该进程处于运行状态。处于此状态的进程的数目小于等于处理器的数目,对于单处理机系统,处于运行状态的进程只有一个。在没有其它进程能够执行时(如全部进程都在阻塞状态),一般会自动执行系统的空闲进程。
-
就绪:当一个进程得到了除处理机之外的一切全部资源,一旦获得处理机便可运行,则称此进程处于就绪状态。就绪状态能够按多个优先级来划分队列。例如,当一个进程因为时间片用完而进入就绪状态时,排入低优先级队列;当进程由I/O操做完成而进入就绪状态时,排入高优先级队列。
-
阻塞:也称为等待或睡眠状态,一个进程正在等待某一事件发生(例如请求I/O而等待I/O完成等)而暂时中止运行,这时即便把处理机分配给进程也没法运行,故称该进程处于阻塞状态。
什么是线程
因为用户的并发请求,为每个请求都建立一个进程显然是行不通的,从系统资源开销方面或是响应用户请求的效率方面来看。所以操做系统中线程的概念便被引进了。
线程有时候被称为轻量级进程,是程序执行流的最小单元。
线程是进程中的一个实体,是被系统独立调度和分配的基本单位,线程本身不拥有系统资源,只拥有一点儿运行中必不可少的资源但它可与同属一个进程的其它线程共享进程所拥有的所有资源。
一个线程能够建立和撤销另外一个线程,同一个进程中的多个线程之间能够并发执行。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派cpu的基本单位指运行中的程序的调度单位。
线程三状态
-
就绪状态:线程具有运行的全部条件,逻辑上能够运行,在等待处理机。
-
运行状态:线程占有处理机正在运行。
-
阻塞状态:线程在等待一个事件(如某个信号量),逻辑上不可执行。
什么是协程
协程是一种用户态的轻量级线程,协程的调度彻底由用户控制。协程拥有本身的寄存器上下文和栈。协称调度切换时,将寄存器上下文和栈保存到其余地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操做栈则基本没有内核切的开销,能够不要加锁的访问全局变量,因此上下文的切换很是快。
线程和进程的区别?
-
一、线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有本身独立的地址空间。
-
二、进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源。
-
三、线程是处理器调度的基本单位,但进程不是
-
四、两者均可以并发的执行
-
五、每一个独立的线程有一个程序运行的入口,顺序执行序列和程序的出口,可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
线程和协程的区别?
-
一、一个线程能够多个协程,一个进程也能够单独拥有多个协程
-
二、线程进程都是同步机制,而协程则是异步
-
三、协称可以保留上一次调用时的状态,每次过程重入的时,就至关于进入上一次调用的状态
什么是多进程?
同一个时间里,同一个计算机系统中若是容许两个或两个以上的进程处于运行状态,这就是多进程 多开一个进程,多分配一份资源,进程间通信不方便
什么是多线程?
线程就是把一个进程分为不少片,每一片均可以是一个独立的流程,与多进程的区别是只会使用一个进程的资源,线程间能够通信
多个概念之间的区别?
-
单进程单线程:一我的在一个桌上吃菜
-
单进程多线程:多我的在一个桌子上吃菜
-
多进程单线程:多我的每一个人在本身桌子上吃菜
同步阻塞模型
多进程:最先的服务器端程序都是经过多进程,多线程来解决并发IO的问题一个请求建立一个进程,而后子进程进入循环同步堵塞地与客户端链接进行交互,收发处理数据。
步骤
-
建立一个socket
-
进入while循环,阻塞在进程accept操做上,等待客户端链接进入主进程在多进程模型下经过fork建立子进程。
多线程模式下能够建立子线程
子线程/线程建立成功后进入while循环,阻塞在recv调用上,等待客户端向服务器发送数据
收到数据之后服务器程序进行处理而后使用send向客户端发送响应
当客户端链接关闭时,子进程/线程退出并销毁全部资源。主进程/线程会回收掉此子进程/线程。
这中模型严重的依赖进程的数量解决并发问题。
启动大量的进程会带来额外的进程调度消耗
异步非阻塞模型
如今各类高并发异步IO的服务器程序都是基于epoll实现的
IO复用异步非阻塞程序使用经典的Reactor模型,Reactor顾名思义就是反应堆的意思,它自己不处理任何数据收发。只是能够监视一个socket句柄的事件变化。
Reactor模型:
1 2 3 4 |
|
nginx:多线程Reactor
swoole:多线程Reactor+多进程worker
php并发编程实战
-
1.php的swoole扩展、并行、高性能网络通讯引擎,使用纯c语言编写提供了php语言的异步多线程服务器,异步tcp/udp网络客户端,异步mysql,异步redis,数据库链接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步dns查询。
-
2.除了异步IO的支持以外,swoole为php多进程的模式设计了多个并发数据结构和IPC通讯机制,能够大大简化多线程并发编程的工做
-
3.swoole2.0支持了相似Go语言的协程,可使用彻底同步的代码实现异步程序
-
4.消息队列
-
5.应用解耦
-
场景说明:用户下单后,订单系统须要通知库存系统。
-
假如库存系统没法访问,则订单减库存将失败,从而致使订单失败
-
订单系统跟库存系统解耦
-
引用队列
-
用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
-
订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操做
-
6.流量削峰 应用场景:秒杀活动,流量瞬间激增,服务器压力大 用户发起请求后,服务器接收后,先写入消息队列。假如消息队列长度超多最大值,则直接报错或提示用户 控制请求量,缓解高流量
-
7.日志处理 应用场景:解决大量日志的传输 日志采集程序将程序写入消息队列,而后经过日志处理程序的订阅消费日志。
-
8.消息通信 聊天室
-
9.常见消息队列产品 kafka,ActiveMQ,ZeroMQ,RabbitMQ,Redis等 php的异步 消息队列
-
10.接口的并发请求 curl_multi_init
mysql缓存层的优化
1.什么是数据库缓存
mysql等一些常见的关系型数据库的数据都存储在磁盘当中,在高并发场景下,业务应用对mysql产生的增删,改,查的操做形成巨大的I/O开销和查询压力,这无疑对数据库和服务器都是一种巨大的压力,为了解决此类问题,缓存数据的概念应运而生。
-
极大的解决数据库服务器的压力
-
提升应用数据的响应速度
常见的缓存形式:内存缓存和文件缓存
2.为何要使用数据库缓存
-
缓存数据是为了让客户端不多甚至不访问数据库服务器进行数据的查询,高并发下,能最大程序地下降对数据库服务器的访问压力。
-
用户请求-》数据查询-》链接数据库服务器并查询数据-》将数据缓存起来(html,内存,json,序列化数据)-》显示给客户端
-
缓存方式的选择
-
缓存场景的选择
-
缓存数据的实时性
-
缓存数据的稳定性
3.使用mysql查询缓存
-
启用mysql查询缓存
-
极大的下降cpu使用率
-
query_cache_type查询缓存类型,有0,1,2三个取值。0则不适用查询缓存。1表示始终使用查询缓存,2表示按需使用查询缓存。
1 |
|
默认状况下query_cache_size为0,表示为查询缓存预留的内存为0,则没法使用查询缓存 SET GLOBAL query_cache_size = 134217728; 查询缓存能够看做是SQL文本和查询结果的映射 第二次查询的SQL和第一次查询的SQL彻底相同,则会使用缓 SHOW STATUS LIKE ‘Qcache_hits’查看命中次数 表的结构和数据发生改变时,查询缓存中的数据再也不有效
情理缓存:
-
FLUSH QUERY CACHE;//清理查询缓存内存碎片
-
RESET QUERY CACHE;//从查询缓存中移出全部查询
-
FLUSH TABLES;//关闭全部打开的表,同时该操做将会清空查询缓存中的内容
4.使用Memcache缓存
对于大型站点,若是没有中间缓存层,当流量打入数据库层时,即使有以前的几层为咱们挡住一部分流量,可是在大并发的状况下,仍是会有大量请求涌入数据库层,这样对于数据库服务器的压力冲击很大,响应速度也会降低,所以添加中间缓存层颇有必要。
memcache是一套分布式的高速缓存系统,由liveJournal的BrandFitzpatrick开发,但目前被许多网站使用以提高网站的访问速度,尤为对于一些大型的、须要频繁访问数据库的网站访问速度提高效果十分显著。 memcache是一个高性能的分布式的内存对象缓存系统,经过在内存里维护一个统一的巨大的hash表,它可以用来存储各类格式的数据,包括图像,视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存,而后从内存中读取,从而大大提升读取速度。
工做流程:先检查客户端的请求数据是否在memcache中,若有,直接把请求数据返回,再也不对数据库进行任何操做;若是请求的数据不在memcache中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中。
通用缓存机制:用查询的方法名+参数做为查询时的key,value对中的key值
5.使用Redis缓存
与memcache的区别:
-
性能相差不大
-
redis在2.0版本后增长了本身的VM特性,突破物理内存的限制,memcache能够修改最大可用内存,采用LRU算法
-
redis依赖客户端来实现分布式读写
-
memcache自己没有数据冗余机制
-
redis支持(快照,aof)依赖快照进行持久化aof加强了可靠性的同时,对性能有所影响
-
redis用户数据量较小的高性能操做和运算上
-
memcache用于在动态系统中减小数据库负载,提高性能;适合作缓存提升性能。
-
可用于存储其余数据:session,session_set_save_handler
mysql数据层的优化
-
数据表数据类型优化:int,smallint.,bigint,enum,ip存储使用int类型ip2long转化存入
-
索引不是越多越好,在合适的字段上建立合适的索引
-
符合索引的前缀原则
-
like查询%的问题
-
全表扫描优化
-
or条件索引使用状况
-
字符串类型索引失效的问题
-
优化查询数据过程当中的数据访问,使用limit,尽可能不要使用*,变复杂为简单,切分查询,分解关联查询*
-
优化特定类型查询语句,优化count(),优化关联查询语句,优化子查询,优化group by和distinct,优化limit和union
-
存储引擎的优化:尽可能使用innodb
-
数据库表结构的优化:分区操做(对用户透明)partion,分库分表(水平拆分,垂直拆分作副表)
-
数据库服务器架构的优化:主从复制,读写分离,双主热备,负载均衡(lvs实现负载均衡,MyCat数据库中间件实现负载均衡)
源码附件已经打包好上传到百度云了,你们自行下载便可~
连接: https://pan.baidu.com/s/14G-bpVthImHD4eosZUNSFA?pwd=yu27
提取码: yu27
百度云连接不稳定,随时可能会失效,你们抓紧保存哈。
若是百度云连接失效了的话,请留言告诉我,我看到后会及时更新~
开源地址
码云地址:
http://github.crmeb.net/u/defu
Github 地址:
http://github.crmeb.net/u/defu
开源不易,Star 以表尊重,感兴趣的朋友欢迎 Star,提交 PR,一块儿维护开源项目,造福更多人!