记录一次公司网站调优过程

这几天公司网站每当业务高峰的时候,就出现如下状况:

1)web服务器CPU负载30~50%左右。(状况正常)

2)Mysql数据库负载正常。

3)连接Redis的Jedis 2.5.2 + common.pool2,一直报can not get a resource。

Jedis Pool的配置是:

timeout=2000

max_total=30

max_idle=5

max_wait=3000


查看redis的监控软件发现redis连接数居然是max_total的3,4倍。


原因分析,及解决方法

1)怀疑,使用jedis的代码没有把获得的资源还回到pool中。但查代码后,确保生产环境程序,在代码层面都将资源还回到pool中了。

问题依旧。


2)既然都还回pool了,就怀疑是不是2周前将jedis从2.0升级到2.5.2。新的jedis-2.5.2,放弃了原先的common.pool,而使用了common.pool2。


由于,近期未更改过代码,仅是jedis升级。所以决定将部署版本还原到jedis-2.0版本。

问题依旧。


3)再次检查代码,[color=red]按照,减少jedis从pool中获取次数,且即使还回pool中的原则。[/color]将下述类似的代码:


for (int i = 0; i < 100; i++) {
Jedis jedis = null;
try {
jedis = getJedisFromPool();
String str = jedis.hget("key");
} catch (TimeoutException e) {
throw e;
}
finally{
if(jedis!=null){
// set jedis back to pool
releaseJedisInstance(jedis);
}
}
}


[color=red][b]修改为:[/b][/color]

String[] keyArr = new String[100]
for (int i = 0; i < 100; i++) {
keyArr[i] = "key" + i;
}

Jedis jedis = null;
try {
jedis = getJedisFromPool();
List<String> result = jedis.hmget(keyArr);
} catch (TimeoutException e) {
throw e;
}
finally{
if(jedis!=null){
// set jedis back to pool
releaseJedisInstance(jedis);
}
}




当天部署后,顺利通过当天第二个业务高峰。


第二天,凌晨0点----6点,Mysql服务器因为负载过高,导致网站瘫痪。


分析及解决方式:

1)分析:查看Mysql的log,发现有个业务,是200多万条数据的A表与200多万条数据的B表,进行了大量的,频繁的left join查询。从而导致大量的慢查询。


解决方式:

a)在B表中冗余字段,建立必要索引。

b)评审代码,优化sql。


2)分析:凌晨,网站开始进行大量后台统计。统计的时候会进行大量的高负载操作。


解决方式:

a)统计在生产库以外的备份出的库上进行。统计数据的查询及使用,也连接备份出的库。

b)去除不必要的统计功能。


3)分析:分析Nginx日志,发现有恶意刷某一页面或功能的请求。


解决方式:

a)增强该部分的代码。

b)在iptable上设置,例如:1分钟内请求大于300次,就屏蔽此IP。


4) 分析:各大搜索引擎,凌晨开始爬虫工作。我们公司网站的历史数据都是未做静态化处理的。


解决方式:历史数据,进行静态化处理。优势,

a)避免不必要的库查询。

b)搜索爬虫,对静态页面的支持更佳,从而提高SEO的效果。

c)静态页面可使用Varnish等,进行缓存操作。


当天夜里,至次日,数据库至此,解决数据库负载过高的情况。


但是,到目前位置,并未完美的且根本解决问题。因为,如果业务高峰再大一些,现有架构的程序依然不能支撑。


描绘一下出问题时的架构:(只画出Redis部分)
[img]http://dl2.iteye.com/upload/attachment/0101/1496/27090601-8a7c-35f6-91c8-9274c369de08.png[/img]

放弃pool连接,改用短连接后的,新的架构:(只画出Redis部分)
[img]http://dl2.iteye.com/upload/attachment/0101/1498/2995bed7-aea4-3d50-b9df-8a43d49cb04e.png[/img]

实现,redis的读写分离,redis主从结构。


在新架构上使用压力测试工具,进行压力测试:

1000并发,1000次请求

1)Web服务器,CPU稳定在150%。

2)Mysql无压力。

3)Redis无压力。

4)Web服务器,Mysql,Redis各个服务器的IO输出正常。

至此问题解决。


总结:

1)代码一定要优化,针对数据库,Redis这样的资源,一定要本着节约的原则。


2)pool 和 短连接比较。

[table]
|| Pool连接 | 短连接|

|扩展性 | 不容易水平扩展| 容易水平扩展|

|稳定性 | 弱,不易实现负载均衡| 强,,易实现负载均衡|

|读写分离 |不容易实现| 容易实现|


[/table]


3)压力测试尽量多做

介绍一个压力测试工具。

siege -c 1000 -r 1000 http://www.baidu.com


当然Apache自带的 ab 工具,WebBench,apache-jmete都是不错的工具。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值