PHP服务性能优化总结

前言

  • 问题都是逐步暴露的,没有显现出来的问题不代表不存在,只是有更低级的问题先出现了而已。
  • 特别是对于 service 来说,问题出现之后,必须要找到根因,找到根因之后,解决方案可以分布实施,否则所谓的中间临时方案很可能只是拆西墙补东墙,甚至可能是错的。做 service 不能抱侥幸心理,问题是一定会出现的。(所以真正的中间方案、临时方案一定是找到根因心里有完整的解决方案后的分步骤实现过程而已)
  • 不同的阶段不同的措施,找到2/8点,四两拨千斤以最小的代价收获最大的效果。
  • 做 service 的严谨性非常重要,前期并不会多花时间,后期反而会节省很多时间。

最先体现出来的问题:用户访问列表、用户信息等速度极慢

原因分析:

  1. 网络?
  2. 数据库访问?
  3. 每次访问数据库都发起了一次连接
  4. 当访问多张表时发起多次连接

改进方案:

  1. 修改数据库主从的位置
  2. 联合查询
  3. 存储过程
  4. 数据库连接池

2/8点:

  1. 将核心流程的数据库查询做存储过程
    效果:
  2. 用户的查询基本控制在 1s 以内了,1s以内的查询对于用户来说可能就基本无感了,因此该阶段暂告一段落

接着出现问题:日本量激增,造成了大量的访问错误(其实访问错误一直存在,只是大家没有关注)

分析:

  1. 基本还认为是网络问题、数据库问题造成访问速度慢,最终导致服务器性能不够
  2. 但是即使激增后的用户量,原理上来说也不可能将我们目前的服务资源消耗完,所以必须要进一步寻找根因

最严重的问题:

  1. IOS APP 在 1s 内发送大量的查询 userinfo 请求,导致服务启动太多的进程消耗完服务器资源
    尝试的改进方案:
  2. 将服务器上除 php 外的其他服务迁移到其他负载低的服务器
  3. 在 APIGateway 上对 userinfo 接口做 60s 的缓存,降低服务的压力(这样用户在一分钟内的频繁请求就会被 API 网关过滤)

效果:

  1. 负载降下来了,在问题出现的时候服务仍然基本处于可用的状态

为什么在 API 网关上做缓存?

  1. 依托于完善的公有云做接口限制,否则服务做限制仍然会消耗掉服务的进程资源
  2. 基于 API 网关做限制其实要求 接口是标准的 rest 风格,缓存都是针对 get 请求的,但是我们的接口并不是 rest,原则上做不了接口缓存。只是由于 userinfo 接口刚好携带有每用户唯一的鉴权头域,能实现方法级的缓存

问题:在 logging 上仍然有访问超时的现象发生

分析:

  1. 偶尔还是出现服务器资源被占完的情况,但是当前同时访问的用户数量其实并不多
  2. 分析日志后发现
  3. API 网关的缓存偶尔会失效,造成一部分压力还是透传到了 php 服务
  4. 但是透传后的压力应该不至于会造成服务器满载
  5. 所以需要从以上两个访问找原因

问题:

  1. APIGateway 的缓存有效期是 60s, 当超过 60s 之后,缓存失效,此时新来的请求还是会透传到后端服务,然后在重建数据,这个机制本身是没问题的。但是问题在于
  2. 第一个请求得到响应的时间太长,有的甚至达到接近 10s,在响应没有回来之前,缓存是无法重建的,所以10s内的并发压力全部透传到了后端服务
  3. 那么问题基本上指向了后端服务,为什么一个请求需要耗时那么久?

尝试的解决方案:

  1. 增加数据库连接池方案 proxysql,解决连接数据库慢的问题
  2. 修改 php-FPM 的配置,将初始进程数量调整到50个,最多的空闲进程调整为52个
  3. 对所有能做 redis 缓存的数据做 redis缓存

效果:

  1. 访问速度加快非常明显,但是在PC上做200个并发访问的时候,仍然有访问超时的现象出现(502,504)

分析:

  1. 发现 nginx 对频繁的访问会自动返回499,对应504

解决方案:

  1. 修改 nginx 的配置

效果:

  1. 504的问题解决了,但是还是会返回502的现象

分析:

  1. FPM的初始进程数量是50个,并发激增的时候创建进程比较耗时

解决方案:

  1. 将初始进程调整为 100个

效果:

  1. 响应时间明显缩短,但是还有少量 502 的现象

分析:

  1. FPM 原理上是一个消耗内存的框架,但是为什么现在是 CPU 先被占满呢?
  2. 打开日志查找慢响应的具体原因,发现
  3. BUG,有一个BUG会导致循环查询一个数据
  4. 其他的 php 服务没有使用数据库代理
  5. Php 服务之间走的是 curl 来访问

解决方案

  1. 解决BUG
  2. 所有的 php 服务都走数据库代理
  3. 要查询数据的时候直接访问代理,不走 curl(其实服务之间的访问走接口会更合理,但是php没有 UDS 等高性能服务)

效果

  1. 在三台 PC上发起测试,基本没有 502 出现,但是后面的请求访问延时仍然偏大

可能的原因:

  1. 开发测试环境的读数据库是在美国,与生产环境相反,生产环境的条件应该要比这个好
  2. 开发测试环境的数据库服务并不是独占资源,有可能数据库本身的访问会被影响
  3. 表设计优化(基于完整的用户故事设计表,而不是单个小需求)
  4. Mysql 查询方法优化
  5. Mysql 本身配置优化
  6. proxysql有更好的配置选项
  7. Php 服务还有继续优化的余地
  8. 服务器本身的配置优化

这个阶段的优化目标已经达到,所以暂时先不往下探索。

过程中我们还计划要做但是没有做的事情:

  1. 对所有的接口做参数的合法性校验
  2. 对所有的接口做调用频率的限制
  3. 做log的代理,用来将服务的错误日志发送到 GCP 的logging,同时将日志文件上传到 S3
  4. 做代码走读,梳理流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/722877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Numpy】给数组增加一个维度

【Numpy】给数组增加一个维度 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您的订阅和支持~ 💡 创…

怎么培养孩子的学习习惯?

问:在亲子阅读中,应该用哪些方法引导孩子自己主动阅读呢? 有很多家长会问如何培养孩子主动阅读的兴趣? 我想给你四个词来分享,分别是环境、选择的权利、适龄,还有增强回路。第一个环境,就是把…

Java @Async 实现异步功能

1.问题描述 在做导入导出功能时,如果数据量比较多,完成操作的时间就会变长,导致页面的接口报502超时异常 2.原因分析 没有做异步处理,同步处理会导致页面要一直等待接口响应,时间一长就会报502 3.解决方案 改为异步导…

html实体字符,看完这篇彻底明白了

二.技术基础知识 基础知识一直都是重点考察的内容,包含有HTML(5)、CSS(3)、JavaScript到 戳这里领取完整开源项目:【一线大厂前端面试题解析核心总结学习笔记Web真实项目实战最新讲解视频】 Vue&#xff0…

MATLAB读取.nc(数据集)文件

MATLAB读取.nc(数据集)文件 以中国1km逐月潜在蒸散发数据集(1901-2022)为例 首先用FileZilla下载特定年份的数据集 用matlab进行处理,代码如下: clear;clc;ncdisp("pet_2022.nc") %读数据集的具体信息和变量eva ncr…

代码训练LeetCode(2)区间列表的交集

代码训练(2)LeetCode之区间列表的交集 Author: Once Day Date: 2024年3月5日 漫漫长路,才刚刚开始… 全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客 参考文章: 986. 区间列表的交集 - 力扣(LeetCode)力扣 (LeetCode) 全球…

flutterprovider局部刷新,简单聊聊2024年Android开发的现状和思考

一、java面试题 熟练掌握java是很关键的,大公司不仅仅要求你会使用几个api,更多的是要你熟悉源码实现原理,甚至要你知道有哪些不足,怎么改进,还有一些java有关的一些算法,设计模式等等。 (一&…

.NET Core 日志记录功能详解

在软件开发和运维过程中,日志记录是一个非常重要的功能。它可以帮助开发者跟踪应用程序的运行状况、诊断和监控问题。.NET Core 提供了一个灵活且易于使用的日志系统,本文将详细介绍.NET Core日志的相关概念、配置和使用方法。 1. 什么是日志记录以及它…

使用GitOps自动化推动AI/ML工作流程

作为一名深耕自动化和人工智能领域的开发人员,我们逐渐认识到尖端工具和方法之间的显着协同作用,这些协同作用突破了可能性的界限。在这次探索中,我们想分享一个概念,它不仅彻底改变了我们的软件开发和基础设施管理方法&#xff0…

向爬虫而生---Redis 探究篇5<Redis集群刨根问底(1)>

前言: Redis集群是一种可靠和高性能的分布式数据库解决方案。随着互联网的迅速发展和数据规模的增长,传统的单机Redis已经无法满足大规模应用的需求。Redis集群的出现填补了这一空白,提供了更高的可扩展性和容错性。 大家都知道,Redis是一种基于内存的高性能键值存储数据库,…

微信小程序开发系列(十七)·事件传参·mark-自定义数据

目录 步骤一:按钮的创建 步骤二:按钮属性配置 步骤三:添加点击事件 步骤四:参数传递 步骤五:打印数据 步骤六:获取数据 步骤七:父进程验证 总结:data-*自定义数据和mark-自定…

绘图设计:用Draw.io绘制图形技巧大全(含统一建模语言UML模板)

一、常见UML模板 1.流程图 2.用例图 include是包含关系,extend是扩展关系 简而言之,include是子集指向父集;而extend是扩展用例指向基础用例(基础用例可以理解为系统核心功能,扩展用例是可选的,不是必须…

易基因:NAR:RCMS编辑系统在特定细胞RNA位点的靶向m5C甲基化和去甲基化研究|项目文章

喜讯!易基因表观转录组学RNA-BS技术服务见刊《核酸研究》 大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 2024年2月15日,吉林大学张涛、赵飞宇、李金泽为共同第一作者,吉林大学李占军、隋婷婷及赖良…

android 键盘遮挡输入框问题回忆

背景 刚开始做Android的时候,有一次遇到输入框位于页面底部,弹出的键盘老是遮挡输入框,这就给人一种感觉----不咋舒服。当时,网上百度了一遍,后面终于解决了,由于当时天天加班,没时间写博客&…

大数据技术学习笔记(五)—— MapReduce(2)

目录 1 MapReduce 的数据流1.1 数据流走向1.2 InputFormat 数据输入1.2.1 FileInputFormat 切片源码、机制1.2.2 TextInputFormat 读数据源码、机制1.2.3 CombineTextInputFormat 切片机制 1.3 OutputFormat 数据输出1.3.1 OutputFormat 实现类1.3.2 自定义 OutputFormat 2 Map…

安卓类加载机制

目录 一、ClassLoader介绍二、双亲委托机制三、类的加载过程 一、ClassLoader介绍 任何一个 Java 程序都是由一个或多个 class 文件组成,在程序运行时,需要将 class 文件加载到 JVM 中才可以使用,负责加载这些 class 文件的就是 Java 的类加…

使用API有效率地管理Dynadot域名,进行DNS域名解析

关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…

如何快速提升算法竞赛水平

学习算法和数据结构:掌握常见的算法和数据结构,如排序算法、树、图等。可以通过参考经典教材、在线教育平台或参加相关课程来学习。 刷题:多进行算法题的练习,可以选择一些经典的OJ(Online Judge)平台&…

linux 将 api_key设置环境变量里

vi ~/.bashrc在最后添加api_key的环境变量 export GEMINI_API_KEYAIza**********WvpX7FwbdM刷新配置 source ~/.bashrc使用python 读取环境变量 import os gemini_api_key os.getenv(GEMINI_API_KEY) print(gemini_api_key)

目标检测YOLO实战应用案例100讲-【目标检测】基于图像处理的机器人垃圾分拣系统

目录 前言 2 基于深度学习的图像处理模型研究 2.1 引言 2.2 卷积神经网络