某项目从3000并发到10W并发的优化记录

某项目从3000并发到10W并发的优化记录

Published  on   04 22, 2017   in   tech with  0  comment

 

最近在做一个某集团一个线上直播的活动,由于时间紧迫,而且项目描述不清。所以开发和部署的时候没有做特别的优化,但是第一次测试的时候问题非常大。主要出在并发上面。这里记录一下优化记录。

背景

因为是临时通知,所以从项目开始到测试仅仅一周时间,所以就快速开发了一个版本,使用 php + mysql,部署的话非常简单的用了一台8核8G的测试服务器,16核16G的正式服务器,lamp 结构。因为给我的员工名单只有10万左右,预计分析的并发量大概有3000-5000,压力测试也没有什么问题。结果活动彩排当天,内部 app 推送、合作厂商 app 内推送、老总发了个微信朋友圈,然后并发在十分钟内过两万,然后就崩了。。。一脸懵逼。

原因

出这么回事当然要写问题报告和整改方案。查看服务器日志发现以下问题。

  • 流量问题

这个问题是最大的,半个小时之内流量达到30T。

  • CPU 问题

间歇性 cpu 达到 100%

  • 数据库问题

间歇性 cpu 达到 100%

分析

  • 流量问题

主要因为前端资源问题,静态资源没有压缩、图片太大、没有使用 CDN、没有延时加载、资源没有合并

  • CPU问题

因为当时在处理别的事情,所以并没有看到当时服务器进程信息,无法确定具体原因。但是分析是因为 apache 多核支持不好、静态资源处理性能不好、而且前端资源大多没有合并、请求数太大,而且没有控制 apache 的连接数和等待时间,导致大量并发堵塞。之后查看 apache 的 log 发下如下错误

[Wed Apr 19 14:01:34.639455 2017] [mpm_prefork:error] [pid 3649] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting

结合其他错误日志和访问日志基本上可以定位到问题

  • 数据库问题

查看数据库的 log 发现主要因为是频繁写入导致。频繁写入只要因为程序中记录用户行为记录导致。

解决

  1. 静态资源压缩、合并、迁移到 cdn

  2. 前后分离、保证静态页面加载速度、数据异步加载、localstorage 缓存部分容灾数据。

  3. 后端使用 redis 缓存常用数据、日志记录加入 redis 队列定时或定量统一入库

  4. 多台服务器进行负载均衡、数据库读写分离、主从同步

  5. apache更换为nginx并升级到最新版

  6. centOs 从 6.8升级到7.3,php5.6升级到php7

实施

服务器部署,大概如下图

静态资源使用 gulp 进行文件的压缩,具体可以参见之前写文章:打造自己的 gulp 前端自动化任务

redis 队列使用实例,


 

$redis->sAdd('jump_list',$_GET['um']); //队列大于100时写入文件 if($redis->ssize('jump_list')>100){ $list=$redis->smembers('jump_list'); //清空队列 $redis->delete('jump_list'); //入库 $time=time(); $ip=$_SERVER["REMOTE_ADDR"]; foreach ($list as $v) { $data[]=[ 'username'=>$v, 'addtime'=>$time, 'type'=>2, 'ip'=>$ip ]; } $database->insert('user_log',$data); }

负载均衡因为时间紧迫,没有自己搭建请求转发服务器,而是使用某云的负载均衡。

文件同步

由于代码部署在多台服务器中,所以测试服务器要和生产服务器文件进行同步,这里使用 scp 进行文件同步。因为用到 shell 的流程就控制所以需要用到 expect 。服务器没有的需要先安装一下。


 

#!/usr/bin/expect -f set password test spawn scp -r /home/wwwroot/default root@10.24.162.xxx:/home/wwwroot set timeout 300 expect "root@10.24.162.xxx's password:" set timeout 300 send "$password\r" set timeout 300 send "exit\r" expect eof

结果

修改之后单台服务器压测并发能达到12000-15000左右。CPU 几乎没有负载。

本文由 lscho 创作,采用知识共享署名4.0国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 03 22, 2018

Responses

展开阅读全文

没有更多推荐了,返回首页