3,第一次并发挑战经验总结
先大致描述一下这个项目服务器端承载的数据量。
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、测试等许多工作。
我并不抵触这样的工作,它能为我建立具有一定广度的知识面。
实际上,只有超牛逼的大公司才会明确好每一个工作岗位,它们的背景足以让它们规范好流程与岗位职责。这也是它们的刚需。
但对我而言,建立知识广度是很有必要的,至于深度,那需要靠自己磨练。
在本次项目中,维护的工作自然是我这个后端来完成,而最主要的维护工作就是数据、服务器出现问题的时候,需要即时抢修。
没有什么日常维护,也没有什么数据指标,监控等等,我的的确确在做抢修,而关键,在于即时。
问题与思考
如果对问题按时间场景进行分类,大致可以分为开发阶段和运行阶段。
而这里,我主要记录一下在运行阶段中,所遇到的问题。
-
问题一:前端angular的变量没有正常输出,以至于在页面上显示了{{$xx.xx}}
这是由于angular的某些核心js没有载入成功而导致的,一般为网络不稳定引起。在服务端,可以采用内容分发的形式减轻服务器压力与提高客户端下载js资源的速度。而客户端网络不稳定的时候,只能采用一些容错的手段,如,当需要的资源没有完全引入的时候,就显示进度条、或给出提示等。
-
**问题二:请求执行时间过长,导致页面某些需要显示动态数据的地方为空白 **
不论是服务端处理速度过慢,还是由于网络原因,出现请求执行时间过长,页面上应该以类似加载进度条的方式给用过一个友善的提醒。另外,既然前后端分离,前端开发者也应该考虑到网络通信失败、服务端接口处理失败等异常情况以及解决方案。
-
**问题三:服务器无法正常提供服务怎么办 **
在使用了阿里云的情况下,对于服务器应硬件设施问题忽然挂掉的情况并不需要考虑太多。
但是,服务器内部的问题,还是需要考虑的,如:服务器资源爆满、服务器某个端口忽然闭掉了、运行的项目里忽然发现一个bug需要修复……
如上所说的情况,我们就必然要对该台服务器的环境、资源、项目代码进行排查,也势必会影响到现有项目的正常运行。
那么,我们就需要考虑到以下几点: -
不到万不得已,山穷水尽,不能影响项目的正常运行和用户的正常使用(关机维护)
-
** 一定不能让用户看到你正在调试 **
-
** 千万不要影响了原有数据和丢失了调试时间段内新增加的数据 **
-
** 操作时必须小心谨慎,避免误操作引发的不可修复的问题 **
-
**一定要做好备份工作 **
-
......
这种情况下, 我的解决方案是这样的:
- 服务是分开的,如mysql和php是处于不同服务器的
- 准备好一套备用的服务环境,如备用php、备用mysql、备用redis等
假设,PHP的服务器出现问题,可先启用备用的PHP服务器,而其他服务都可以照常进行,等解决了问题,再将PHP服务迁回原有服务器。
实际上网上有很多更好的方案,只是那些方案不论是从成本还是场景,都不太适合我现在的项目情况。
- **问题四:当项目遇到意外情况怎么办 **
项目运行后,将接受广大网民的考验,出现意外情况也在所难免。对此,我只能够在运行之前,尽可能多的,想到运行后可能发生的情况(这很大一部分取决于策划者或者负责人的经验)。
想到越多可能发生的意外,就准备好相应的应急方案,在运行后遇到对应的问题,就可以快速启动应急方案。
应急方案后端有义务去思考,但并不是所有应急方案都是后端的职责。每一端都有可能出现问题,而不是只要一有问题就是后端的锅。
当然,针对数据这一块,后端最好尽可能的把日志系统给完善起来,这样,当出现某些棘手的问题时,这些数据就是根基。
- ** 问题五:Mysql占用CPU资源过高,导致服务器几乎崩溃 **
Mysql消耗了过多的性能,基本上是在执行某条sql语句的时候卡掉的,那就查看一下mysql的子进程。
show processlist
可以看到在是哪一条sql语句让mysql卡住的,再针对性的优化这条语句。
另外,如果有必要,也可以根据explain做一些索引优化。请求较大的时候,也可以在配置中修改一下mysql的最大链接数
- ** 问题六:请求量过大导致nginx返回502错误 **
502错误的原因有很多,但本次项目中的502错误,主要是因为请求量太大,导致php-fpm进程达到了最大限制。这里,只需要去调整一下php-fpm的配置,再把允许的子进程数增加到合适的数量,顺便给分配一个合理的内存。
最后,重启php-fpm服务。
- ** 问题七:遭遇恶意洪水攻击 **
我的解决方法是开通了百度的cdn服务,它的cdn服务自带cc和ddos防御
经验总结
- 从项目宏观角度出发,我需要做好以下几点:
- 预备应急方案
-
提高资金安全性
-
项目开发完成,应做好功能测试与性能测试
-
前端应做好容错处理和优化
-
要建立齐全、完善、可利用的日志系统
-
设置一个风险预警以及即时通知,让工作人员可以即时处理风险
-
PHP / Laravel / Mysql
- 原始表达式 DB::raw()方法的使用
- 分组查询时,在查询字段上使用 max、sum等函数可统计该组的数据
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)