独立的图片服务器有诸多好处,其中一个就是客户端浏览器对一个主机下的链接数量限制,具体的链接数目忘记了,但基本都在10如下。也就是说,浏览器会控制一个站点下的并发请求数量在10如下,若是对于网站有不少样式文件、脚本文件和图片须要加载的话,请求的过程会被阻塞,影响网站的打开速度。 php
创建图片服务器,将图片资源放在另一个域名下面,会在必定程度上提高网站的打开速度,这样来讲的话是否是说咱们独立的服务器越多越好呢?也不尽然,解析域名并创建链接也须要很长的时间,独立的主机多了的话,也不利于速度的提高。html
图片每每会消耗掉网站中的不少宽带和IO资源,独立的图片服务器能够在宽带和IO性能上单独提高,便于管理和拓展。nginx
请求动态内容:web
php –>域名->DNS解析找到对应ip地址->返回给客户端->客户端找到真实的服务器->80端口web服务->nginx 判断是否为php->反向代理->php-fpm PHP解析器->php代码内容解析->html代码->浏览器算法
什么是动态语言静态化?sql
将现有PHP等动态语言的逻辑代码生成为静态HTML文件,用户访问动态脚本重定向到静态HTML文件的过程,适合用于对实时性要求不高的页面数据库
为何要静态化?编程
动态脚本一般会作逻辑计算和数据查询,访问量越大,服务器压力越大浏览器
访问量大时可能会形成CPU负载太高,数据库服务器压力过大静态化能够减低逻辑处理压力,下降数据库服务器查询压力。缓存
静态化的实现方式
1.使用模板引擎:常见的模板引擎可使用Smarty,Smarty的缓存机制生成静态HTML缓存文件
$smarty->cache_dir = $ROOT."/cache"; //缓存目录 $smarty->caching = true; //是否开启缓存 $smarty->cache_lifetime = "3600"; //缓存时间 $smarty->display(string template[,string cache_id[,string compole_id]]); $smarty->clear_all_cache();//清除全部缓存 $smarty->clear_cache('file.html'); //清除指定的缓存 $smarty->clear_cache('article.html',$art_id);//清除同一个模板下的指定缓存好的缓存
2.利用ob系列的函数
ob_start();//打开输出控制缓冲 ob_get_contents(); //返回输出缓冲区内容 ob_clean(); //清空输出缓冲区 ob_end_flush(); //冲刷出(送出)输出缓冲区内容并关闭缓冲 //示例 ob_start(); 输出到页面的HTML代码... ob_get_contents(); ob_end_flush(); fopen() 写入
//1.判断当前文件是否有修改,2.判断是否存在缓存文件 3.判断缓存文件是否过时
<?php
$cache_name = md5(__FILE__).'.html'; $cache_lifetime = 3600;//缓存时间 if(filectime(__FILE__) <= filectime($cache_name)&&file_exists($cache_name) && filectime($cache_name)+ $cache_lifetime > time() ){ include $cache_name; exit; } ob_start(); ?> <b>html 代码</b> <?php $content = ob_get_contents(); ob_end_flush(); $handle = fopen($cache_name, 'w'); fwrite($handle,$content); fclose($handle); //根据id 作不一样缓存 $id = $_GET['id']; if(empty($id)){ $id = ''; } $cache_name = md5(__FILE__). '-'.$id.'.html';
在了解并发处理以前须要了解相关概念:
什么是进程、线程、协程
什么是多进程、多线程
同步阻塞模型
异步非阻塞模型
进程:
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操做系统结构中的基础 进程是一个“执行中的程序”
进程的三态模型:运行、就绪、阻塞
进程的五态模型:新建态、终止态、活跃就绪、静止就绪、活跃阻塞、静止阻塞
参考:https://www.cnblogs.com/xiawen/p/3328033.html
线程:
线程是程序中一个单一的顺序控制流程。进程内一个相对的、可调度的执行单位,是系统独立调度和分派CPU的基本单位
线程的状态: 参考:https://blog.csdn.net/kzadmxz/article/details/73437926
协程
参考:http://www.sohu.com/a/237171690_465221
进程与线程的区别:
1.线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有本身独立的地址空间
2.进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
3.线程是处理器调度的基本单位,但进程不是
4.两者都可并发执行
5.每一个独立的线程有一个程序的运行的入口,顺序执行序列和程序的出口,可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多线线程执行控制
线程与协程的区别:
1.一个线程能够拥有多个协程,一个进程也能够单独拥有多个协程
2.线程进程都是同步机制,而协程则是异步
3.协程能保留上一次调用时的状态,每次过程重入时,就至关于进入上一次调用的状态
多线程多进程:
https://zhidao.baidu.com/question/282409258.html
同步、异步、阻塞、非阻塞
https://www.cnblogs.com/George1994/p/6702084.html
了解完以上相关概念后,php相关的并发编程有哪些呢?
PHP的swoole拓展
swoole是php的异步、并行、高性能网络通讯引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库链接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询,除了异步IO的支持以外,Swoole为PHP多进程的模式设计了多个并发数据结构和IPC通讯机制,能够大大简化多进程并发编程的工做
消息队列
常见消息队列产品:Kafka、ActiveMQ、ZeroMQ、RabbitMQ、Redis等
应用场景:
注册:将注册信息写入数据库成功后,将成功信息写入队列,此时直接返回成功给用户,写入队列的时间很是短,能够忽略不计,而后异步发送邮件和短信
下单:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功,订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息进行库存操做
秒杀活动:用户瞬时激增,用户发起请求,服务器接收后,先写入消息队列,假如消息队列长度超过最大值,则直接报错或提示用户
解决大量日志的传输:日志采集程序将程序写入消息队列,而后经过日志处理程序的订阅消费日志
聊天室:多个客户端订阅同一主题,进行消息发布和接收
接口的并发请求
curl_multi_init
什么是数据库缓存?
MySQL等一些常见的关系型数据库的数据都存储在磁盘当中,在高并发场景下,业务应用对MySQL产生的增、删、改、查的操做形成巨大的I/O开销和查询压力,这无疑对数据库和服务器都是一种巨大的压力,为了解决此类问题,缓存数据的概念应运而生。
常见的缓存形式:内存缓存,文件缓存
为何要使用缓存?
缓存数据是为了让客户端不多甚至不访问数据库服务器进行数据的查询,高并发下能最大程度地下降对数据库服务器的访问压力
用户请求-->数据查询-->链接数据库服务器并查询数据-->将数据缓存起来(HTML、内存、JSON、序列化数据)-->显示给客户端
用户再次请求或者新用户访问-->数据查询-->直接从缓存中获取数据-->显示给客户端
MySQL的查询缓存
query_cache_type
查询缓存类型,有0 1 2三个取值,0则不使用查询缓存,1表示始终使用查询缓存,2表示按需使用查询缓存
query_cache_type 为1时,亦可关闭查询缓存
SELECT SQL_NO_CACHE * FROM my_table WHERE condition;
query_cache_type为2时,可按需使用查询缓存
SELECT SQL_CAHCE * FROM my_table WHERE condition;
query_cache_type为0时,表示为查询缓存预留的内存为0,则没法使用查询缓存
SET GLOBAL query_cache_size = 134217728
查询缓存能够看作是SQL文本和查询结果的映射
第二次查询的SQL和第一次查询的SQL彻底相同,则会使用缓存SHOW STATUS LIKE 'Qcache_hits';查看命中次数
表的结构或数据发生改变时,查询缓存中的数据再也不有效
清理缓存:
FLUSH QUERY CACHE; //清理查询讯缓存内存碎片
RESET QUERY CACHE; //从查询缓存中移出全部查询
FLUSH TABLES; //关闭全部打开的表,同时该操做将会清空查询缓存中的内容
使用Memcache缓存查询数据
对于大型站点,若是没有中间缓存层,当流量打入数据库层时,即使有以前的几层为咱们挡住一部分流量,可是在大并发的状况下,仍是会有大量请求涌入数据库层,这样对于数据库服务器的压力冲击很大,响应速度也会降低,所以添加中间缓存层颇有必要
memcache是一套分布式的高速缓存系统,对于一些大型的、须要频繁访问数据库的网站访问速度提高效果十分显著
工做原理:
memcache是一套高性能的分布式的内存对象缓存系统,经过在内存里维护一个统一的巨大的hash表,它可以用来存储各类格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存,而后从内存中读取,从而大大提升读取速度
工做流程:
先检查客户端的请求数据是否在memcached中,若有,直接把请求数据返回,再也不对数据库进行任何操做;若是请求的数据再也不memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时吧数据缓存一份到memcached中
方法:获取:get(key) 设置:set(key,val,expire) 删除:delete(key)
通用缓存机制: 用查询的方法名+参数做为查询时的key value对中的key值
使用Redis缓存查询数据
与Memcahce 的区别:
性能相差不大
Redis在2.0版本后增长了本身的VM特性,突破物理内存的限制,Memcache能够修改最大的可用内存,采用LRU算法
Redis,依赖客户端来实现分布式读写,Memcache自己没有数据冗余机制
Redis支持(快照、AOF)依赖快照进行持久化,aof加强了可靠性的同时,对性能有所影响
Redis用于数据量较小的高性能操做和运算上 Memcache用于在动态系统中减小数据库负载,提高性能;适合作缓存,提升性能
数据表数据类型优化
字段使用什么样的数据类型更合适
字段使用什么样的数据类型性能更快
tinyint smallint bigint --- 考虑空间的问题,考虑范围的问题
char varchar --- 存储字符长度是否固定
enum --- 特定、固定的分类可使用enum存储,效率更快
ip地址的存储 使用整型存储ip地址
索引优化
创建合适的索引
索引在什么场景下效率最高
索引不是越多越好,在合适的字段上建立合适的索引
复合索引的前缀原则 ---Abc三个字段复合索引 查询条件为a AND b 能够 b AND c a AND c 不能够
like查询%的问题 ---like 百分号在前索引失效
全表扫描优化 ---全表扫描自动失效
or条件索引使用状况 --- Or 前面有后面无则索引失效
字符串类型索引失效问题 --- 字符串查要加引号
SQL语句的优化
优化查询过程当中的数据访问 ---使用limit 返回列不用*
优化长难句的查询语句 ----变复杂为简单 切分查询 分解关联查询 分次删除
优化特定类型的查询语句 ---优化count() 优化关联查询 优化子查询 优化GROUP BY 和distinct 优化limit和union
存储引擎的优化
一、MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,并且不支持外键,若是执行大量的select,insert MyISAM比较适合。
二、InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特色。若是有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的状况
参考 https://www.cnblogs.com/y-rong/p/8110596.html
数据表结构设计的优化
分区操做:经过特定的策略对数据表进行物理拆分 对用户透明 partiton by
分库分表:水平拆分(活跃数据和不活跃数据 union) 垂直拆分(经常使用和不经常使用列 join)
数据库服务器架构的优化
主从复制
读写分离
双主热备
负载均衡
MYSQL负载均衡: 经过LVS的三种基本模式实现负载均衡 MyCat数据库中间件实现负载均衡
web服务器负载均衡:七层负载均衡的实现 四层负载均衡的实现