PHP性能优化

avatar
作者
筋斗云
阅读量:11

mysql5.7连接数据库_php7连接mysql数据库_mysqli连接数据库

1.2 Apache Benchmark (ab工具)

查看测试结果

php7连接mysql数据库_mysql5.7连接数据库_mysqli连接数据库

n: 要模拟的请求数;c: 要模拟的并发请求数;t: 执行模拟所需要的时间

1.3 Siege

Siege可以模拟托管文档的用户流量,与ab不同的是,Siege可以对文本文件中指定的URL列表运行负载测试。它还可以在执行其它请求之前让某个请求休眠,从而让你感觉某个用户在转移到Web应用程序的下一个文档之前正在读取该文档。

php7连接mysql数据库_mysql5.7连接数据库_mysqli连接数据库

php7连接mysql数据库_mysql5.7连接数据库_mysqli连接数据库

-c 200 指定并发数200-r 5 指定测试的次数5-f urls.txt 制定url的文件-i internet系统,随机发送url-b 请求无需等待 delay=0-t 5 持续测试5分钟 [H,M,S--时分秒,默认M]-r和-t一般不同时使用

1.4 影响基准测试数字

2.提高客户端下载和呈现性能

2.1 概述

Web服务器发送的响应的细节信息;

分析JavaScript中的前端逻辑;

浏览器将读取的资源的逐项列表;

浏览器获取和接受资源所花费的时间;

对如何优化响应的建议

2.2 Firebug

好吧,我没用过,个人觉得Chrome自带的就够用了

mysqli连接数据库_php7连接mysql数据库_mysql5.7连接数据库

还可以看时间花费细节:

mysqli连接数据库_php7连接mysql数据库_mysql5.7连接数据库

2.3 YSlow

优化规则:

2.3.1 CSS优化2.3.2 图像优化2.3.3 JavaScript优化

2.4 YUI Compressor和Closure Compiler

这两个是JavaScript精简工具

现在不都是用gulp和webpack了吗?

2.5 图像压缩

使用Smush.it工具

3. PHP代码优化

3.1 PHP最佳实践

一些小tips

3.2 使用VLD、strace和Xdebug一探究竟

pecl install channel://pecl.php.net/vld-0.14.0 安装

测试代码

echo 'hello' , 'World!';

执行

php -dvld.active=1 test.php

结果

Finding entry pointsBranch analysis from position: 0Jump found. (Code = 62) Position 1 = -2filename:       /apps/www/test/test.phpfunction name:  (null)number of ops:  5compiled vars:  noneline     #* E I O op                           fetch          ext  return  operands-------------------------------------------------------------------------------------   2     0  E >   EXT_STMT                                                          1        ECHO                                                     'hello'         2        EXT_STMT                                                          3        ECHO                                                     'World%21'   3     4      > RETURN                                                   1
branch: # 0; line: 2- 3; sop: 0; eop: 4; out1: -2path #1: 0, helloWorld!

3.3 发现瓶颈

Xdebug是面向PHP的调试器和概要分析工具,除了更多的调试信息外,Xdebug还可以为开发人员提供如下的信息:

举例

xdebug_start_trace('/tmp/trace', XDEBUG_TRACE_APPEND ); //开始,日志写到/tmp/trace文件class Node {    public $val; //值    public $d; //距离    public $p; //父节点    public $linkedNodes = [];//连接的顶点    public function __construct($val){        $this->val = $val;    }}

/** * Dijkstra **/class DijkstraAlgorithm{ /** * 生成图 * @param array $vertex * @return array */ public function buildGraph($vertex){ $graph = []; $nodes = array_keys($vertex); foreach ($nodes as $node) { $graph[$node] = new Node($node); } foreach ($vertex as $key => $item) { foreach ($item as $value) { if (isset($graph[$value])) { $graph[$key]->linkedNodes[] = $graph[$value]; } } } return $graph; }
/** * 初始化操作 * @param array $graphNodes * @param Node $s */ public function init(&$graphNodes, &$s){ foreach ($graphNodes as $graphNode) { $graphNode->d = 9999999; } $s->d = 0; }
/** * 松弛操作 * @param Node $u * @param Node $v * @param Array $w * @return bool */ public function relax(&$u, &$v, $w){ $d = $u->d + $w[$u->val . '_' . $v->val]; if($v->d > $d) { $v->d = $d; $v->p = $u; return true; } return false; }
/** * 从队列取出最小距离的顶点 * @param array $queue */ public function extractMin(&$queue){ $result = []; foreach ($queue as $item) { $result[$item->d] = $item; } ksort($result); $queue = array_values($result); return array_shift($queue); }
/** * Dijkstra 算法 * 问题1:没考虑到负环路 * @param $graphNodes * @param $s */ public function dijkstra(&$graphNodes, $s, $w){ $this->init($graphNodes, $s); $gather = []; $queue = $graphNodes; while (!empty($queue)) { $node = $this->extractMin($queue); $gather[] = $node; foreach ($node->linkedNodes as $linkedNode) { if($this->relax($node, $linkedNode, $w)) { if(!in_array($linkedNode, $queue)) { array_push($queue, $linkedNode); } } } } }}

//顶点$vertex = [ 'a' => ['b', 'c'], 'b' => ['d'], 'd' => ['e'], 'c' => ['e'], 'e' => [],];//边的权重$w = [ 'a_b' => 1, 'a_c' => 3, 'b_d' => 2, 'd_e' => 2, 'c_e' => 4,];
$g = new DijkstraAlgorithm();$graphNodes = $g->buildGraph($vertex);$g->dijkstra($graphNodes, $graphNodes['a'], $w);
$w = [ 'a_b' => 1, 'a_c' => 3, 'b_d' => 2, 'd_e' => 2, 'c_e' => 4,];xdebug_stop_trace();//结束行为追踪

centos的php.ini配置:

[xdebug]zend_extension="/apps/install/php/lib/php/extensions/no-debug-non-zts-20151012/xdebug.so"xdebug.remote_enable = 1xdebug.trace_format = 1xdebug.auto_trace = 0xdebug.trace_output_dir = /tmp/xdebug.trace_output_name = trace.%c.%p
xdebug.collect_params = 4xdebug.collect_includes = Onxdebug.collect_return = Onxdebug.show_mem_delta = Onxdebug.var_display_max_depth = 2

分析结果

mysqli连接数据库_mysql5.7连接数据库_php7连接mysql数据库

以上看起来不是很清晰,可以借助这个PHP进行分析:

用法:


usage:        php run-cli tracefile [sortkey] [elements]
Allowed sortkeys: calls, time-inclusive, memory-inclusive, time-own, memory-own //后四个分别指包含子方法的耗时, 包含子方法的内存消耗,自己方法的耗时,自己方法体的内存消耗

示例:

php tracefile-analyser.php trace.log.xt time-inclusive 20 //获取最耗时的20个方法

结果:

Showing the 20 most costly calls sorted by 'time-inclusive'.
Inclusive Ownfunction #calls time memory time memory----------------------------------------------------------------------------------------------------------------------------------------- 1 5.8553 12017136 5.8553 12017136common\services\qmyx\BuildingInfoService->getBuildingList 1 1.7179 3559752 0.0038 -457592common\repositories\qmyx\MyParamValueRepository->getParamOptionByScopeIdAndValueAndParamCode 45 1.3890 914592 0.0126 -275240yii\db\ActiveQuery->one 46 1.3441 1012584 0.0062 704yii\db\Query->one 46 1.2831 951440 0.0055 -323104yii\db\Command->queryInternal 52 1.1350 1326664 0.0155 3504yii\db\Command->queryOne 47 0.9962 1061744 0.0038 0PDOStatement->execute 52 0.8573 634848 0.8573 634848yii\db\ActiveQuery->createCommand 50 0.3639 268176 0.0090 -56976yii\db\QueryBuilder->build 50 0.2823 78424 0.0150 -133952yii\db\QueryBuilder->buildCondition 295 0.1507 32400 0.0082 10392yii\db\QueryBuilder->buildWhere 50 0.1488 27376 0.0025 224yii\BaseYii::createObject 73 0.1318 5219896 0.0062 0yii\db\QueryBuilder->buildAndCondition 92 0.1316 22928 0.0060 -8896yii\db\Command->queryAll 4 0.1239 247608 0.0002 0yii\di\Container->get 75 0.1239 5219896 0.0051 0yii\di\Container->build 75 0.1189 5219896 0.0083 18056yii\log\Logger->log 156 0.1131 739152 0.0470 -2074992ReflectionClass->newInstanceArgs 75 0.1009 5022912 0.0037 99568common\services\project\ProjectService->filterDisabledProjectIdsByAppCode 1 0.0961 596344 0.0003 -4880



4. Opacode缓存

4.1 回顾路线图

mysqli连接数据库_mysql5.7连接数据库_php7连接mysql数据库

4.2 PHP的生命周期

php7连接mysql数据库_mysqli连接数据库_mysql5.7连接数据库

image.png

在此补充一下,php7新加了语法解析树。

应用了Opcode缓存的PHP生命周期:

mysqli连接数据库_mysql5.7连接数据库_php7连接mysql数据库

4.2 Opcode缓存工具

现在用opcache啦~~

5. 变量缓存

mysqli连接数据库_mysql5.7连接数据库_php7连接mysql数据库

缓存可以用memcached或者redis等中间件。

6. 选择正确的Web服务器

并发当然是选择nginx

7. 优化Web服务器和内容交付

大部分是针对Apache的优化,略过。

还有负载均衡、共享会话、分布式架构的一些问题(缓存一致性、缓存版本等等)、监控应用程序Ganglia、Cacti、Nagios。

8. 数据库优化

“工作集”就是经常使用的数据集,如果这个数据集可以轻松地放到内存中,性能的提高也基本上就到了极限,特别是当拥有一个好的索引集时。

1). top监控进程

mysql5.7连接数据库_mysqli连接数据库_php7连接mysql数据库

image.png

2). iostat查看I/O性能

mysqli连接数据库_mysql5.7连接数据库_php7连接mysql数据库

选项 说明

mysql5.7连接数据库_php7连接mysql数据库_mysqli连接数据库

若 %iowait 的值过高,表示硬盘存在I/O瓶颈

若 %idle 的值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量

若 %idle 的值持续低于1,则系统的CPU处理能力相对较低,表明系统中最需要解决的资源是 CPU

mysqli连接数据库_php7连接mysql数据库_mysql5.7连接数据库

image.png

3).Mysqltuner.pl

当你看到较高的%util或%iowait值,那么应该查看驱动器的性能,或者看看打开的一些MySQL内存缓冲区以减少MySQL服务器命中磁盘所需的时间。但该系统没有显示I/O性能的任何问题,因此我们可以继续进行。

Mysqltuner.pl可以减轻配置和检查数据服务器的大量工作。

mysqli连接数据库_mysql5.7连接数据库_php7连接mysql数据库

image.png

mysql5.7连接数据库_mysqli连接数据库_php7连接mysql数据库

image.png

-- show variables like '%max_connections%'; 查看最大连接数

set global max_connections=1000 重新设置


mysql> show status like 'Threads%';+-------------------+-------+| Variable_name | Value |+-------------------+-------+| Threads_cached | 58 || Threads_connected | 57 | ###这个数值指的是打开的连接数| Threads_created | 3676 || Threads_running | 4 | ###这个数值指的是激活的连接数,这个数值一般远低于connected数值+-------------------+-------+ Threads_connected 跟show processlist结果相同,表示当前连接数。准确的来说,Threads_running是代表当前并发数 这是是查询数据库当前设置的最大连接数mysql> show variables like '%max_connections%';+-----------------+-------+| Variable_name | Value |+-----------------+-------+| max_connections | 1000 |+-----------------+-------+ 可以在/etc/my.cnf里面设置数据库的最大连接数[mysqld]max_connections = 1000****命**令:show processlist;****如果是root帐号,你能看到所有用户的当前连接。如果是其它普通帐号,只能看到自己占用的连接。****show processlist;****只列出前100条,如果想全列出请使用****show full processlist;**[MySQL](http://lib.csdn.net/base/14 "MySQL知识库")> show processlist;
**命令:show status;**
**命令:show status like '%下面变量%';**
Aborted_clients 由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。Connections 试图连接MySQL服务器的次数。Created_tmp_tables 当执行语句时,已经被创造了的隐含临时表的数量。Delayed_insert_threads 正在使用的延迟插入处理器线程的数量。Delayed_writes 用INSERT DELAYED写入的行数。Delayed_errors 用INSERT DELAYED写入的发生某些错误(可能重复键值)的行数。Flush_commands 执行FLUSH命令的次数。Handler_delete 请求从一张表中删除行的次数。Handler_read_first 请求读入表中第一行的次数。Handler_read_key 请求数字基于键读行。Handler_read_next 请求读入基于一个键的一行的次数。Handler_read_rnd 请求读入基于一个固定位置的一行的次数。Handler_update 请求更新表中一行的次数。Handler_write 请求向表中插入一行的次数。Key_blocks_used 用于关键字缓存的块的数量。Key_read_requests 请求从缓存读入一个键值的次数。Key_reads 从磁盘物理读入一个键值的次数。Key_write_requests 请求将一个关键字块写入缓存次数。Key_writes 将一个键值块物理写入磁盘的次数。Max_used_connections 同时使用的连接的最大数目。Not_flushed_key_blocks 在键缓存中已经改变但是还没被清空到磁盘上的键块。Not_flushed_delayed_rows 在INSERT DELAY队列中等待写入的行的数量。Open_tables 打开表的数量。Open_files 打开文件的数量。Open_streams 打开流的数量(主要用于日志记载)Opened_tables 已经打开的表的数量。Questions 发往服务器的查询的数量。Slow_queries 要花超过long_query_time时间的查询数量。Threads_connected 当前打开的连接的数量。Threads_running 不在睡眠的线程数量。Uptime 服务器工作了多少秒。
My.ini配置 虚拟内存
[](http://www.pc51.net/data/MySQL/2007-01-04/2551.html)
innodb_buffer_pool_size=576M ->128M InnoDB引擎缓冲区
query_cache_size=100M ->32 查询缓存tmp_table_size=102M ->32M 临时表大小key_buffer_size=16m ->8M
**设置max_connections**
**命令:show variables like '%max_connections%'** (这个办法在debian+mysql Ver 12.22 Distrib 4.0.22, for pc-[Linux](http://lib.csdn.net/base/linux "Linux知识库") (i386)里实验了)设置办法是在my.cnf文件中,添加下面的最后红色的一行:
--------------------------------------------------------------------------------
[mysqld]port=3306#socket=MySQLskip-lockingset-variable = key_buffer=16Kset-variable = max_allowed_packet=1Mset-variable = thread_stack=64Kset-variable = table_cache=4set-variable = sort_buffer=64Kset-variable = net_buffer_length=2Kset-variable = max_connections=32000(在院里的DELL机器mysql4.0里的语法不同max_connecionts=2000直接这么写就好了

--------------------------------------------------------------------------------
修改完毕后,重启MySQL即可。当然,为了确保设置正确,应该查看一下max_connections。
注意:1、虽然这里写的32000。但实际MySQL服务器允许的最大连接数16384;2、除max_connections外,上述其他配置应该根据你们系统自身需要进行配置,不必拘泥;3、添加了最大允许连接数,对系统消耗增加不大。4、如果你的mysql用的是my.ini作配置文件,设置类似,但设置的格式要稍作变通。
用mysqld --help 可以查看到max_connections 变量。 或者 mysql -uuser -p**后mysql>show variables;也会看到max_connections 。**
下面是修改张老师 的redhat9的方法:
先是mysql -uw01f -pmysql>show variables;看到max_connections 为100mysql>exit;vi /etc/my.cnf [mysqld]set-variable=max_connections=250 #加入这些内容:wq
/etc/init.d/mysqld restart

php7连接mysql数据库_mysql5.7连接数据库_mysqli连接数据库

想要获取学习实战、高并发、架构、笔试面试资料

请扫码咨询+薇薇微信

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!