高性能分布式架构实践(一)

先把普通企业级基本性能优化的小方法复习下

JVM 参数调优

1.      使用64JDK 1.6+ & Tomcat 6+

2.      jvm内存优化

编辑tomcat/bin/目录下catalina.batlinuxcatalina.sh,配置类似,请自行百度),在文件开头加上以下代码(注意先搜索一下,不要重复设置)

3.   set JAVA_OPTS=-Xms512m -Xmx4096m -XX:PermSize=128m-XX:MaxPermSize=256m

以上设置的含义为:
堆内存最小512M,最大4G,非堆内存最小128M,最大256M,对于系统规模小、访问量不大的项目可酌情将-Xmx4096m设置为-Xmx2048m(2G)

深度优化
对于访问量较大,集成比较复杂的系统,需要利用 JDK 中的内存分析工具,分析内存的变化情况(一般是在生产环境中分析实际内存使用情况) , 并酌情修改内存参数,
如将堆内存的最大值设置为 -Xmx8000m ,一般最大值不超过系统内存的 2/3

常用的分析工具有JDK bin目录中的jconsole.exe jvisualvm.exe


HTTP 连接数调优

编辑tomcat/conf/目录下server.xml,在访问端口对应的<Connector>中增加和连接数相关的属性:
minSpareThreads:最小空闲连接线程数,默认值10
maxSpareThreads(Tomcat6之前的版本有一个maxSpareThreads参数,但是在7中已经移除了):最大空闲连接线程数,
maxThreads:最大连接线程数,并发处理的最大请求数,默认值200
acceptCount:等待队列,指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。默认值为100
connectionTimeout:请求超时时间,默认是20秒
推荐配置tomcat7:
<Connector port="8080" protocol="HTTP/1.1" maxThreads="800" minSpareThreads="50" acceptCount="800"
connectionTimeout="30000" redirectPort="8443" />
注:并发能力问题涉及整个系统物理环境、架构和业务逻辑,要根据情况动态调整,web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右

其他属性配置参考官方文档


数据库调优

连接数调优

对于Oracle数据库,默认最大连接数为150,可通过下面的SQL来查询和修改(DB2 9.7+、MS SQL SERVER 2008+默认不限制连接数)

select count(*) from v$process --当前的连接数

select value from v$parameter where name = 'processes' --数据库允许的最大连接数
--修改最大连接数,一般设置为1500-3000,重启数据库服务后生效:
alter system set processes = 1500 scope = spfile;

索引

索引是什么?请百度
索引的性能提高测试,参考http://www.cnblogs.com/xwdreamer/archive/2012/05/03/2480449.html
建立索引的一般规则:
1. 为查询条件中的字段建立索引,通常这些字段应该为状态值等字典字段或日期字段
2. 仅左like('xx%')查询会使用索引,其他like('%xx%'或'%xx')查询不会使用索引
3. 索引并不是越多越好,索引会降低插入和更新的速度,因为当insert或Update的时候要更新索引
4. 巧用唯一索引,确保数据的唯一性

分区分表

什么是分区、分表,请自行百度。
1. 只有针对大表,分区分表才有意义;一般大表是指记录数在百万级的,至少也是几十万;否则请考虑其他优化方式
2. 相对而言,优先考虑分区,因为分表需要修改代码逻辑
3. 常用的分区一般为范围分区和列表分区

连接池调优

无论是JNDI数据源,还是DBCP连接池,都有一些链接池参数,这些参数的设置参考如下:
<property name="minPoolSize" value="10"/><!--连接池中保留的最小连接数。-->
<property name="maxPoolSize" value="100"/>  <!--连接池中保留的最大连接数。Default: 15,一般为300以内-->
<property name="initialPoolSize" value="10"/>  <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。过大则启动过慢 -->
<property name="maxIdleTime" value="60"/><!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->

<property name="acquireIncrement" value="5"/><!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3,此数严禁过大 -->


功能优化

从功能设计上,避免一次性加载大量数据。遇到一次性加载大量数据的,通过以下问题寻找功能优化方式:

1.       设置默认查询条件,仅加载部分数据。如对于监测数据的查询分析,可默认仅查询当天或当月的数据;

2.       将数据展示使用类似TAB的元素分开,根据用户操作,采用AJAX分步加载数据

3.       实时性要求不高的数据,不要实时查询,可缓存或者放到Session

代码调优

SQL优化

1.       尽量使用join,不要使用子查询

2.       可能的情况下,尽量使用UNION ALL来代替UNION

小窍门:
可使用PL/SQL 或者 SQLServer Management Studio查看SQL的执行计划,进而对SQL进行优化。

缓存的使用

关于EhCache、Redis的使用,请自行百度。 

耗时操作的处理

需求:对某事项进行审批,审批通过后发邮件给提交人。 
发邮件即为一个耗时操作,如果审批通过后,在当前线程中执行发邮件的操作,则会阻塞当前线程,直到邮件发送结束。 

经验分享:

耗时操作可以启动一个新的线程执行,避免阻塞当前线程(request)

或者将耗时操作仅仅设置一个未执行的状态,后台跑一个QZ任务,定时批量执行。

代码逻辑调优

1.       避免for 多层嵌套

2.       避免对大数组的迭代对比,考虑使用Arrays.binarySearch()


静态文件优化

静态文件优化主要是指对文件大小的优化。
文件大小往往被很多开发人员忽略,但对于带宽有限(公网项目)或者硬件设备(主要是交换机)老旧的环境,文件大小往往是性能的最大瓶颈。
试想一个index.action,所有文件通过浏览器另存之后大小为3M,则100并发,就需要3*100 = 300M的瞬时流量,需要300 * 8 = 2.4Gbps的带宽才能在1秒内下载完毕(粗算,不科学)

1.       不要引用重复的、没必要的jscss文件

2.       对于jscss文件较大的,需要压缩

3.       不要使用>100K的图片

网络优化

测试环境的网络拓扑

需求:某外网系统首页要求满足100用户并发访问,响应时间<3秒,此首页所有资源文件的总大小为1.5M(浏览器另存)。
如果测试工程师在自己家里的电脑上用LoadRunner测试,或者在思路公司的内网环境下测试,均不能达标,为什么?
因为家庭带宽一般<20Mbps,且一般家庭都采用了一些家用路由,如TP-link xx型号等,思路公司内网环境同样有层层交换机(设备旧),而且出口众多(分流很大)
造成LoadRunner测试机本身的带宽不够,无法承受接收100个用户的并发流量模拟。 
结论:
LoadRunner
程序本身的性能测试最好将测试客户机同服务器直接连接在一个企业级交换机上,排除网络因素。

带宽问题

参见上述静态文件大小、测试环境的网络拓扑,得出结论:
带宽很重要。要做压力测试,首选将测试机同服务器直连到同一个企业级交换机(千兆以上)上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值