84669 personnes étudient
152542 personnes étudient
20005 personnes étudient
5487 personnes étudient
7821 personnes étudient
359900 personnes étudient
3350 personnes étudient
180660 personnes étudient
48569 personnes étudient
18603 personnes étudient
40936 personnes étudient
1549 personnes étudient
1183 personnes étudient
32909 personnes étudient
1、今天被问一个问题:请问具体到PHP的代码层面,改善高并发的措施有哪些?
面对高并发问题我首先想到的是集群、缓存(apt、redis、mem、内存...),但具体到PHP代码层面除了想到队列、减少网络请求,想不到别的了,所以开了这个讨论贴,希望大神留下可行方案。
业精于勤,荒于嬉;行成于思,毁于随。
我觉得 PHP 代码层面的话,那就直接从 PHP 的相关知识点出发
PHP
项目的 SESSION 处理机制,files->DB->Cache
SESSION
项目的 Log 记录情况,files->DB
Log
资源复用、长时间操作异步处理,单例、全局数据共享,队列等
字节码缓存 APC,XCACHE,OPCACHE
APC
XCACHE
OPCACHE
数据(view)缓存,文件缓存(files)->本地缓存(Yac)->分布式缓存(MEMCACHE,REDIS)
框架选择,微框架(Lumen)->全栈PHP框架(SF,LARAVEL)->扩展框架(Yaf,Phalcon)->并行框架(Yar)
PHP 版本选择, PHP5.x->hhvm->php7
是面试时候的问题吗?
估计是面试公司实际开发时候遇到相关的问题,就拿来当面试问题
具体到代码方面,现在通常谈到提高并发能力,可以借鉴nodejs的思路,就是异步,非阻塞式的访问,以保证高并发,所以你可以谈谈php都有哪些异步操作的扩展,比如我搜了一下有个叫做swoole的扩展。还有就是把计算任务更多的交到前端,减少服务器端的计算,提高响应速度。还有就是操作数据库,可能谈一谈如何修改数据库的组织形式(减少join之类的操作)也不错
唯快不破!
10ms一次的请求, 比100ms一次的请求, 压力会小10倍, 因为你的并发是有限的, 如果一个连接进来后, 迟迟不完结, 就会占用资源不释放, 容易发生同一时间内存在大量并发连接. CPU和内存满的时候, 会恶性循环卡死, 所以要设好连接数上限.
然后, 绝大多数人有这个毛病(我们公司到处有这样代码), 未优化的大量数据I/O:
// 取用户的订单列表 $orders = api_get_orders($uid); // 可是, 订单里没有商品的详情, 怎么做呢? foreach($orders as $i=>$order){ // api_get_good_by_id 是个缓存或mysql IO $orders[$i]['good'] = api_get_good_by_id($order['goodid']); } return $orders;
循环中产生了大量的IO, 如果平均一用户一次数据20个订单数据, 10个并发请求就产生了200个数据库/缓存IO
把它们合并为一个IO:
// 取用户的订单列表 $orders = api_get_orders($uid); // 提取goodid序列 $goodids = array_map(function($o){ return $o['goodid']; }, $orders); // 一次性把商品全部取出来 $goods = api_get_goods_by_ids( $goodids ); // 封装到$orders foreach($goods as $i=>$g){ $orders[$i]["good"] = $g; } return $goods;
有时候会大量的从缓存中读同一个key的数据, 如果我们加了一级runtime cache, 有了一次缓存IO, 下次直接从php变量中取, 岂不是更快? 类似我们在方法内用 static 缓存一些稳定不变的数据. 当然,别忘了封装缓存delete, set的时候, 清除或更新runtime缓存.
对, 一切都是为了减少IO和提高复用, 计较那些什么算法排序能快点, 意义不大, sql语句优化除外
对象资源复用 例如单例模式 实例化一个数据库对象 这个对象共用减少对数据的IO开销
我也了解的比较浅,我就知道,能少请求数据库就尽量少请求,存库的数据如果不急的话的就放redis,然后做定时任务去跑。
一般最怕的应该是对同一条数据的更新问题,比如说跟新库存。这种采用队列就能解决了。
我觉得
PHP
代码层面的话,那就直接从PHP
的相关知识点出发项目的
SESSION
处理机制,files->DB->Cache项目的
Log
记录情况,files->DB资源复用、长时间操作异步处理,单例、全局数据共享,队列等
字节码缓存
APC
,XCACHE
,OPCACHE
数据(view)缓存,文件缓存(files)->本地缓存(Yac)->分布式缓存(MEMCACHE,REDIS)
框架选择,微框架(Lumen)->全栈PHP框架(SF,LARAVEL)->扩展框架(Yaf,Phalcon)->并行框架(Yar)
PHP
版本选择, PHP5.x->hhvm->php7是面试时候的问题吗?
估计是面试公司实际开发时候遇到相关的问题,就拿来当面试问题
具体到代码方面,现在通常谈到提高并发能力,可以借鉴nodejs的思路,就是异步,非阻塞式的访问,以保证高并发,所以你可以谈谈php都有哪些异步操作的扩展,比如我搜了一下有个叫做swoole的扩展。
还有就是把计算任务更多的交到前端,减少服务器端的计算,提高响应速度。
还有就是操作数据库,可能谈一谈如何修改数据库的组织形式(减少join之类的操作)也不错
唯快不破!
10ms一次的请求, 比100ms一次的请求, 压力会小10倍, 因为你的并发是有限的, 如果一个连接进来后, 迟迟不完结, 就会占用资源不释放, 容易发生同一时间内存在大量并发连接. CPU和内存满的时候, 会恶性循环卡死, 所以要设好连接数上限.
然后, 绝大多数人有这个毛病(我们公司到处有这样代码), 未优化的大量数据I/O:
循环中产生了大量的IO, 如果平均一用户一次数据20个订单数据, 10个并发请求就产生了200个数据库/缓存IO
把它们合并为一个IO:
缓存驱动设计一层 runtime cache
有时候会大量的从缓存中读同一个key的数据, 如果我们加了一级runtime cache, 有了一次缓存IO, 下次直接从php变量中取, 岂不是更快? 类似我们在方法内用 static 缓存一些稳定不变的数据. 当然,别忘了封装缓存delete, set的时候, 清除或更新runtime缓存.
对, 一切都是为了减少IO和提高复用, 计较那些什么算法排序能快点, 意义不大, sql语句优化除外
对象资源复用 例如单例模式 实例化一个数据库对象 这个对象共用
减少对数据的IO开销
我也了解的比较浅,我就知道,能少请求数据库就尽量少请求,存库的数据如果不急的话的就放redis,然后做定时任务去跑。
一般最怕的应该是对同一条数据的更新问题,比如说跟新库存。这种采用队列就能解决了。