ThinkPHP 3.2 性能优化,实现高性能API开发

需求分析

目前的业务全站使用ThinkPHP 3.2.3,前台、后台、Cli、Api等。目前的业务API访问量数千万,后端7台PHP 5.6,平均CPU使用率20%。

测试数据

真实业务

php5.6:500 QPS

php7.0:850 QPS

真实业务中减少一次Mysql查询业务或者减少一次Redis读写

php5.6:800 QPS

php7.0:1250 QPS

目前优化的结果:

ThinkPHP可以完整的跑在缓存中;

在不需要mysql查询时,不建立mysql连接;

不读写redis时,不建立redis连接。

以上数据在开发机器使用ab获取,同时也跟其它的框架做了简单对比,性能不低于其它框架。

使用zend debugger profile 可以看到框架层的时间开销占比约24%,相对于yaf这样的C语言框架10%的性能损失,一个包含缓存和ORM的框架已经算比较好的性能了。

再次吐槽一提ThinkPHP框架就喷性能不好的人,任何一个框架拿过来多做几次数据库操作,测试性能都渣得不逼,只测试输出一个HelloWorld并什么卵用。

优化过程

0x00

在项目中早期,开发压力大,没有什么时间进行项目和架构优化。

经过测试,通过添加 mysql 长连接和redis长连接,api稳定性得到非常大提升,业务最慢响应时间从4s优化到0.5s,曲线非常平稳。

PHP-FPM单机200进程,2000Request,7台PHP后端,长连接数稳定在1700左右。

产生的问题长连接数超过5k时,性能会下降。出现过两次Mysql Server 内存用光的情况。

0x01

经过分析,发现很多API请求,是不需要建立Mysql连接的。调整代码,Mysql的查询逻辑尽量缓存到Redis里,减少对Mysql的压力。

同时对ThinkPHP的代码逻辑进行化,调用 Model 中的方法、属性,不建立Mysql连接,只有在读写db时才建立连接。减少了非常多的资源开销。

经过上述调整,Mysql的连接从1700下降到100以内,query and read QPS从5k下降到50。

优化的ThinkPHP的代码已推送到Github:

https://github.com/vus520/thinkphp/tree/shuhai/db_link_lazzy

后续是对ThinkPHP中Mysql主从、读写分离进行深度测试,增加Mysql的读能力。

0x03

当业务都严重依赖redis时,Redis的QPS一度飙升到7k,内存占用6G左右。

为了缓解redis的读压力,生产中使用了4台Redis Standalone做了1主3从架构。

并给ThinkPHP添加Redis读写分离的支持,减少Redis的压力。

https://github.com/vus520/thinkphp/blob/shuhai/db_link_lazzy/ThinkPHP/Library/Think/Cache/Driver/Redisd.class.php

目前存在的问题

Redis的高可用运维,本身也比较复杂,遇上网络抖动等原因,Redis会出现同步失败和延迟问题。

特别是在云服务器架构的环境中,网络瓶颈和延迟问题对分布式应用有非常大的影响。

很可惜,我们目前使用的青云,目前尚不能实现Redis超高可用,也不能实现无缝扩容,私网内的网络传输性能、延迟都有很大优化空间。

后续的优化计划

对redis业务进行清理,减少不必要的请求;

压缩内容;

key:value => hash;

一主多从,每个php后端部署一个redis从,优先读本机,减少网络延迟;

0x04

API项目中,禁用ThinkPHP的Session、路由、视图、行为等,进行精简加速。经测试,性能有30%的提升。

https://github.com/vus520/thinkphp/tree/shuhai/tiny

  • 1,去掉路由
  • 2,去掉URL调度
  • 3,去掉行为、Hook
  • 4,去掉视图
  • 5,去掉控制器的反射、空操作
  • 6,去掉Session,可实现无状态的Api

0x05

在PHP7中进行深度测试,升级到PHP7,ThinkPHP 3.2的性能会有50+%的提升

原文地址:https://www.cnblogs.com/onew/p/10939472.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


(1)创建数据表: CREATE TABLE IF NOT EXISTS `think_form` (   `id` smallint(4) unsigned NOT NULL AUTO_INCREMENT,
组合查询的主体还是采用数组方式查询,只是加入了一些特殊的查询支持,包括字符串模式查询(_string)、复合查询(_complex)、请求字符串查询(_query),混合查询中的特殊查询每次查询只能定义一个,由于采用数组的
(1)创建模版:/App/Home/View/Form/edit.html   <FORM method=\"post\" action=\"__URL__/update\">
自定义配置文件user.php: <?php return array(    \'sex\'=>\'man\', ); config.php: <?php return array(
在一些成熟的CMS系统中,后台一般都包含一个配置中心(如织梦后台中系统设置),以方便站长在后台修改配置文件;那么这个功能是如果实现的呢?在ThinkPHP中有没有捷径可走呢?答案肯定是有的。下面大概说一下这个功能
废话不多说先上图预览下,即本博客的分页; 这个分页类是在thinkphp框架内置的分页类的基础上修改而来,原分页类的一些设计,在实际运用中感觉不是很方便;
在php中截取字符串的函数有很多,而在thinkphp中也可以直接使用php的函数,本文给大家简单的介绍thinkPHP模板中截取字符串的具体用法,希望能对各位有所帮助。
thinkphp开发图片上传,图片异步上传是目前比较方便的功能,这里我就不写css文件了,将代码写出来。
配置数据库:/app/Common/Conf/config.php 方法一: // 添加数据库配置信息 \'DB_TYPE\'   => \'mysql\',// 数据库类型
/app/Home/Controller/IndexController.class.php
(1)创建数据表: CREATE TABLE IF NOT EXISTS `think_data` (   `id` int(8) unsigned NOT NULL AUTO_INCREMENT,
(1)控制器设置:/app/Home/Controller/IndexController.class.php <?php namespace HomeController; use ThinkController;
(1)普通模式 http://localhost/index.php?m=module&a=action&var=value m参数表示模块,a操作表示操作(模块和操作的URL参数名称是可以配置的),后面的表示其他GET参数。
入库的时候用htmlspecialchars()处理含有html代码的内容 输出的时候用htmlspecialchars_decode()处理含有html代码的内容
<?php define(\'APP_NAME\',\'app\'); define(\'APP_PATH\',\'./app/\'); define(\'APP_DEBUG\',TRUE); // 开启调试模式
(1)创建控制器中定义read方法:/App/Home/Controller/FormController.class.php public function read($id=0){
一、实现不同字段相同的查询条件 $User = M(\"User\"); // 实例化User对象 $map[\'name|title\'] = \'thinkphp\';
如果你的数据完全是内部操作写入而不是通过表单的话(也就是说可以充分信任数据的安全),那么可以直接使用add方法,如:
查询表达式的使用格式: $map[\'字段名\'] = array(\'表达式\',\'查询条件\'); 表达式不分大小写,支持的查询表达式有下面几种,分别表示的含义是:
一、使用字符串作为查询条件 $User = M(\"User\"); // 实例化User对象 $User->where(\'type=1 AND status=1\')->select();