需求分析

目前的业务全站使用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+%的提升

ThinkPHP 3.2 性能优化,实现高性能API开发的更多相关文章

  1. 【前端性能优化】高性能JavaScript整理总结

    高性能JavaScript整理总结 关于前端性能优化:首先想到的是雅虎军规34条然后最近看了<高性能JavaScript>大概的把书中提到大部分知识梳理了下并加上部分个人理解这本书有参考雅 ...

  2. Java性能优化之高性能JAVA代码的若干个习惯

    创建对象: 1.避免在循环体中创建对象,循环前应该创建对象,避免浪费更多内存空间和增加GC负担 这种情况在我们的实际应用中经常遇到,而且我们很容易犯类似的错误,例如下面的代码: for (int i ...

  3. 【转载】 Spark性能优化指南——基础篇

    转自:http://tech.meituan.com/spark-tuning-basic.html?from=timeline 前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能 ...

  4. 【转】Spark性能优化指南——基础篇

    http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=2651805828&idx=1&sn=2f413828d1fdc6a ...

  5. Spark性能优化指南——基础篇(转载)

    前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作 ...

  6. Spark性能优化指南——基础篇

    本文转自:http://tech.meituan.com/spark-tuning-basic.html 感谢原作者 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一 ...

  7. Spark性能优化(一)

    前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作 ...

  8. Spark性能优化指南——基础篇转

    前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算操作 ...

  9. Spark性能优化指南--基础篇

    前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能复用同一个RDD 原则三:对多次使用的RDD进行持久化 原则四:尽量避免使用shuffle类算子 原则五:使用map-side预聚 ...

随机推荐

  1. redis 中 set 和 hset 有什么不同,什么时候使用 hset 什么时候使用set?

    转载:https://blog.csdn.net/wab719591157/article/details/73379844 redis 中存数据时,到底什么时候用  hset 相比于 set 存数据 ...

  2. 使用jstl报错:Can not find the tag library descriptor for “http://java.sun.com/jstl/core”

    使用jstl报错:Can not find the tag library descriptor for “http://java.sun.com/jstl/core” 出现这个错误的原因是项目中没有 ...

  3. vmware产品框架-计算中心,5.1更新等

    概述:SRM,5.1新特性,vCenter Operations的介绍等 5.1改进参见:http://wenku.baidu.com/view/26530362a98271fe910ef961.ht ...

  4. angularjs中的坑

    ng-show 等ng的指令中不需要使用{{parameter}}来取值,回无效

  5. ES6学习笔记十:模块的导入、导出

    一:模块导入 1) import { 要导入的属性.方法民 } from '模块路径'; 2)该种方法需要有配置文件,指明模块所在路径 import { 要导入的属性.方法民 } from '模块名' ...

  6. Linux(centos)新建,删除,移动,重命名文件夹和文件的命令

    1.新建文件夹 mkdir 文件名 新建一个名为test的文件夹在home下 view source1 mkdir /home/test 2.新建文本 在home下新建一个test.sh脚本 vi / ...

  7. 6、redis之使用spring-data-redis的Template

    POM: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o ...

  8. java 怎么打印变量

    //Test.java public class Test16{ public static void main(String args[]){ int age=28; System.out.prin ...

  9. Qt Installer Framework 使用说明(一)

    目录 Qt Installer Framework 使用说明 1.Qt Installer Framework概述 选择安装包类型 促进更新 提供安装内容 2.入门指南 支持的平台 从源代码构建 支持 ...

  10. 使用eclipse生成文档(javadoc)主要有三种方法:

    使用eclipse生成文档(javadoc)主要有三种方法: 1,在项目列表中按右键,选择Export(导出),然后在Export(导出)对话框中选择java下的javadoc,提交到下一步. 在Ja ...