编程/12 分钟阅读

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

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

背景

因为是临时通知,所以从项目开始到测试仅仅一周时间,所以就快速开发了一个版本,使用 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

实施

服务器部署,大概如下图

QQ截图20170423141529.png

静态资源使用 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 几乎没有负载。

发表评论

0 条评论

暂无评论