PHP的学习PHP经验分享

3,第一次并发挑战经验总结

2017-02-07  本文已影响210人  陈钢镚学财

先大致描述一下这个项目服务器端承载的数据量。

PHP进程并发峰值 300+
Mysql进程并发峰值 100+
接口返回数据峰值 45/s
用户量 1.2w+
接口总处理次数 34w+
游戏数据 6w+

以上数据,也只能算是项目背景的一个部分。


接下来,再从以下几个方面把整个项目从策划到运营进行总结

项目背景


周期:从提出项目计划到上线,共计12个工作日(边开发边决定项目需求,这非常紧迫)
开发人员:1个后端 ,2个web前端
选型:后端(laravel+thinkphp),前端(Jquery + angular)
服务器环境:CentOS,php7,nginx,mysql

配置


2核4G 和 1核2G 阿里云 ECS 各一台

架构


首先,既然前端都用上了ng,那么前后端分离是必然的,后端的支持全以接口的形式提供。
或许很多人都认为,前后端分离,后端的工作量轻松了很多,但本质上,这种看法是不对的。

** 前后端分离,只是为了更加明确前端与后端的工作岗位,让后端可以更专注的去完成除实现逻辑以外的那些必要工作,如服务器安全、数据安全、接口安全、处理效率与性能、第三方服务的交互、各种处理日志、服务器拓机的应急解决方案等等 **

本次项目中,因为后端由我一人负责,我便把一直以来自己没来得及实践的想法搬上了项目。(实际上,并不是很建议这么做,因为想法没有实践,终究存在很多未知性)
开发中,我把后端架构,大致分为了三大系统:

实现


同以往开发的项目一样,在实现阶段,它依然保持着固定的几个步骤:

开发步骤是灵活的,每个团队每个开发人员,都有自己的风格和场景。
所以,只有适合团队适合自己且适合当前业务需求的开发步骤就是最好的开发流程。
当然,尽管适合团队,适合自己,但流程也是要与时俱进的,它需要得到合理的升级。

维护


因为这个团队的特殊性,我并没有一个很明确的工作岗位。
我可能是以后端开发为主要工作,但同时,你可能要兼任项目策划、服务器管理、服务器运维、项目维护、DBA、测试等许多工作。
我并不抵触这样的工作,它能为我建立具有一定广度的知识面。

实际上,只有超牛逼的大公司才会明确好每一个工作岗位,它们的背景足以让它们规范好流程与岗位职责。这也是它们的刚需。

但对我而言,建立知识广度是很有必要的,至于深度,那需要靠自己磨练。
在本次项目中,维护的工作自然是我这个后端来完成,而最主要的维护工作就是数据、服务器出现问题的时候,需要即时抢修。
没有什么日常维护,也没有什么数据指标,监控等等,我的的确确在做抢修,而关键,在于即时

问题与思考


如果对问题按时间场景进行分类,大致可以分为开发阶段运行阶段
而这里,我主要记录一下在运行阶段中,所遇到的问题。

这种情况下, 我的解决方案是这样的:

  1. 服务是分开的,如mysql和php是处于不同服务器的

假设,PHP的服务器出现问题,可先启用备用的PHP服务器,而其他服务都可以照常进行,等解决了问题,再将PHP服务迁回原有服务器。
实际上网上有很多更好的方案,只是那些方案不论是从成本还是场景,都不太适合我现在的项目情况。

项目运行后,将接受广大网民的考验,出现意外情况也在所难免。对此,我只能够在运行之前,尽可能多的,想到运行后可能发生的情况(这很大一部分取决于策划者或者负责人的经验)。
想到越多可能发生的意外,就准备好相应的应急方案,在运行后遇到对应的问题,就可以快速启动应急方案。
应急方案后端有义务去思考,但并不是所有应急方案都是后端的职责。每一端都有可能出现问题,而不是只要一有问题就是后端的锅。
当然,针对数据这一块,后端最好尽可能的把日志系统给完善起来,这样,当出现某些棘手的问题时,这些数据就是根基。

Mysql消耗了过多的性能,基本上是在执行某条sql语句的时候卡掉的,那就查看一下mysql的子进程。

show processlist

可以看到在是哪一条sql语句让mysql卡住的,再针对性的优化这条语句。
另外,如果有必要,也可以根据explain做一些索引优化。请求较大的时候,也可以在配置中修改一下mysql的最大链接数

502错误的原因有很多,但本次项目中的502错误,主要是因为请求量太大,导致php-fpm进程达到了最大限制。这里,只需要去调整一下php-fpm的配置,再把允许的子进程数增加到合适的数量,顺便给分配一个合理的内存。
最后,重启php-fpm服务。

我的解决方法是开通了百度的cdn服务,它的cdn服务自带cc和ddos防御

经验总结


  1. 预备应急方案
  1. 原始表达式 DB::raw()方法的使用
SELECT sum(`money`) AS money FROM `users` GROUP BY `openid`

SELECT count(*) FROM (SELECT * FROM users GROUP BY openid) a
-- 该条语句不会不会消耗太大性能,从本质上将,仅相当于执行了两次select

 - laravel读取配置,需要指定文件名 如 config('app.xxx')

 - laravel的/app文件夹下的文件都支持自动加载

 - dd() 和 dump() 的使用

 - 配置文件可以在config文件夹下随意新增,controller可以在controllers文件夹下随意增删(规范命名空间)

 - 使用DB时,须引入DB类,DB支持原生sql查询和查询构造器

 - Laravel查询构造器的连贯操作

 - Laravel查询后,记录以对象的形式返回

 - Laravel缓存的使用,须引入cache类

 - php://input ,当PHP的get和post环境变量不支持某个请求提交的格式时,若要读取数据,则需要从输入流中读取

- 微信
 1. 网页开发授权的access_token和基本access_token是不同的
 - 微信现金红包功能,发红包时需要携带证书,而证书路径必须指定正确,可用绝对路径
 - php curl的post默认只支持一维数组,若数据较复杂,可以json形式传递


# 总结
***
平心而论,这个项目所给的时间是不充分的,能够在最终顺利结束,已是不易。
同样,也毫不客气的讲,整个项目中,我的贡献是最大的。
贡献越大,得到的回报也越多,我从这个项目中得到的经验也是弥足珍贵的。

[本文出自半醒的狐狸博客](http://blog.vsonweb.com/post/51.shtml)
上一篇下一篇

猜你喜欢

热点阅读