关于 Java Web 项目性能提升的一些思路

使用 Nginx 作为前端接入

  用 Nginx 进行动静分离。这个不用多讲,新浪、网易、淘宝、腾讯等巨头的使用已经说明了一切。

  保持最简单的架构

  遵守 KISS 原则(Keep it simple and stupid)。尽量不要考虑项目外的重用。过多的考虑项目外的重用,必然会增加项目的复杂度。避免过度集成,让每个模块只做自己的事,这对于日后的维护和模块复用都有好处。

  精心设计缓存处理、毫不吝啬代码(对象、列表、片段)

  对于门户网站的首页来说,往往可能会有近百个 SQL。用户并发上去以后,光首页就足以让服务器 down 掉。缓存不但有利于降低负载,而且还能提高响应速度。

  调整使用聚集索引

  对于每个表来讲,聚集索引只有一个,利用好了,查询速度会有意想不到的提升效果。

  以 MySql 为例,InnoDB选取聚集索引参照列的顺序是

  1. 如果声声明了主键(primary key),则这个列会被做为聚集索引;

  2. 如果没有声明主键,则会用一个唯一且不为空的索引列做为主键,成为此表的聚集索引;

  3. 上面二个条件都不满足,InnoDB会自己产生一个虚拟的聚集索引。


CREATE TABLE `timeline_raw` (

`rawId` bigint(20) NOT NULL AUTO_INCREMENT,

`uid` bigint(20) DEFAULT NULL,

`did` bigint(20) DEFAULT NULL,

`channelId` char(1) NOT NULL DEFAULT '1' COMMENT '1:qvga; 2:720p',

`fileId` bigint(20) DEFAULT NULL,

`sectionId` bigint(20) DEFAULT NULL,

`headerFilePath` varchar(120) DEFAULT NULL,

`startTime` bigint(20) DEFAULT NULL,

`endTime` bigint(20) DEFAULT NULL,

`updateTime` datetime DEFAULT NULL,

`createTime` datetime DEFAULT NULL,

PRIMARY KEY (`rawId`),

KEY `index_uid_did_startTime` (`uid`,`did`,`startTime`) USING BTREE,

KEY `index_uid_did_endTime` (`uid`,`did`,`endTime`) USING BTREE,

KEY `index_time` (`startTime`) USING BTREE,

KEY `index_uid_did_fileId` (`uid`,`did`,`sectionId`) USING BTREE,

KEY `index_sectionId` (`sectionId`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

  这个表有四个索引:主键 rawId、sectionId、`uid`,`did`、startTime。

 项目的 iBatis2 中有这样一条查询语句:


<select id="getRawFileList" parameterClass="java.util.HashMap" resultClass="com.defonds.mysql.raw.entity.TimelineRaw">

SELECT * FROM timeline_raw_

WHERE uid=#uid#

AND did=#did#

AND channelId=#channelId#

<isNotNull  property="sectionId"> AND sectionId = #sectionId#</isNotNull>

AND

(

(startTime BETWEEN #startTime# and #endTime#)

OR

(endTime BETWEEN #startTime# and #endTime#)

OR

(

<![CDATA[

startTime<=#startTime#

]]>

AND

<![CDATA[

endTime>=#endTime#

]]>

)

)

ORDER BY startTime;

</select>

  根据实际业务向 timeline_raw 表注入一千万条数据,进行模拟测试(参考《sql 性能测试例子》),发现 getRawFileList 的执行平均时间为 160 ms 以上。这是不能接受的。

  考虑到实际业务中对于主键 rawId 查询条件甚少,我们把rawId主键索引取消掉,改为唯一约束,却把sectionId+startTime+endTime作为主键(业务上能够保证其唯一性,根据InnoDB索引规则,这个索引将成为我们新表的聚集索引)。然后把sectionId、startTime两个索引也取消掉,仅保留`uid`,`did`索引。

  这样子,我们新表的索引实际上只有两个了:一个聚集索引(sectionId+startTime+endTime)一个非聚集索引(`uid`,`did`)。

  再次进行模拟测试,同样的数据、数据量,同样的查询结果集,getRawFileList 执行平均时间已经降到了 11 ms。结果是令人振奋的,不是么?

  使用 /dev/shm 来存储缓存的磁盘文件

  在网站运维中,利用好了这一点,往往有意想不到的收获。以 tomcat 为例,可以通过修改 catalina.sh 中的 CATALINA_TMPDIR 值的路径来将缓存设置为 /dev/shm。

  以 OSC 为例,他们就是纯 Java 写的,部署在 tomcat 下。在长时间的在线运行之后,管理员发现网站响应速度奇慢,服务器负载正常,又找不出是哪里的问题。后来 df 一下,发现 tomcat 临时目录下的文件足足有 8G 之多,原来是 CPU 等待磁盘操作造成响应速度加长。于是他们将临时目录映射到 /dev/shm,网站响应速度从此奇快。

  分析系统中每一个 SQL 的执行效率

  以 MySql 为例,对于每个 SQL 最好都 explain 一下。对于有明显效率问题的,通过 sql 优化、调索引等方法进行改进。

  健康慢查询日志,检查所有执行超过 100 毫秒的 SQL

  对于上线了的项目,健康慢查询日志,检查所有执行超过 100 毫秒的 SQL,看看有没有优化余地。对于没有上线的项目,可以进行场景模拟对嫌疑 SQL,或者对频繁使用的 SQL 进行性能测试,统计它们执行时间,得出平均值,画出曲线分析图,对于单表千万数据,执行时间超过 50ms 的 SQL 要重点关注。参考《sql 性能测试例子》。

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2025-01-21 09:52:42

关于 Java Web 项目性能提升的一些思路的相关文章

java web项目中应用的服务器推送技术都有哪些?有没有性能问题

问题描述 java web项目中应用的服务器推送技术都有哪些?有没有性能问题 java web项目中应用的服务器推送技术都有哪些?有没有性能问题 解决方案 Web实时推送,选择GoEasy推送服务, 代码简单易懂,几分钟就可以自己写好一个在线聊天demo. 中英文文档齐全.官网:https://goeasy.io 解决方案二: 目前,websocket是个很好的方向. 解决方案三: websocket. http://blog.csdn.net/jiangcs520/article/detail

实例jie如何提高Java Web 服务性能优化实践

本文介绍如何提升 Java Web 服务性能,主要介绍了三种方法:一是采用 Web 服务的异步调用,二是引入 Web 服务批处理模式,三是压缩 SOAP 消息.重点介绍在编程过程中如何使用异步 Web 服务以及异步调用和同步调用的差异点.本文还示范了如何在项目中使用以上三种方法,以及各种方法所适合的应用场景. Java Web 服务简介 Web 服务是一种面向服务架构的技术,通过标准的 Web 协议提供服务,目的是保证不同平台的应用服务可以互操作.Web 服务(Web Service)是基于 X

云服务器 ECS 建站教程:手工部署Java Web项目

手工部署Java Web项目 Tomcat 一个开源的且免费的 Java Web 服务器,常用来作为 web 开发的工具.它可以托管由 servlet,JSP 页面(动态内容),HTML 页面,javascript,样式表,图像(静态内容)组成的 Java Web 应用程序. 此外,将来随着业务的扩展,您可以利用阿里云强大的产品平台,平滑地横向和纵向扩展服务容量,例如: 扩展单个 ECS 实例的 CPU 和内存规格,增强服务器的处理能力. 增加多台 ECS 实例,并利用负载均衡,在多个实例中进行

编程-在weblogic上部署JAVA WEB项目,为什么关闭之后最小的连接数不会自动关闭

问题描述 在weblogic上部署JAVA WEB项目,为什么关闭之后最小的连接数不会自动关闭 在项目中设置的最小连接数是2 初始连接数是5,当我开启这个项目的时候发现连接池中的连接数加了5个,因为我设置了maxIdleTime属性,过了一会有3个连接数因为空闲会被关闭,但是那2个最小的连接数一直不会关闭,就算在服务器上把这个应用停止了也不会关闭,这要怎么处理呢? 项目是spring+strtuts2+hibernate 连接池用的是c3p0 解决方案 出于性能的考虑,底层连接池会保持连接,这是

有人做过软件的版本升级工作吗.Java Web项目。

问题描述 有人做过软件的版本升级工作吗.Java Web项目. 如题,现在有个项目要从版本3,升级到4.要考虑到兼容性,还要有功能上的提升.请问大神.你们是怎么做的.给一些建议. 谢谢. 解决方案 我现在做的最多的就是项目的维护和升级,没遇到过兼容问题.一般都是添加新的功能,和修复反馈的bug.一般不会考虑更换第三方资源的版本.不清楚你的兼容性值的是什么?

Java web项目为什么要单独配置环境变量?

问题描述 Java web项目为什么要单独配置环境变量? Spring的配置文件中的代码如下: class=""org.springframework.beans.factory.config.PropertyPlaceholderConfigurer""> 在运行项目的时候需要配置环境变量之后才能运行,这事为什么呢?希望大神们可以帮我解惑一下,谢谢! 解决方案 这不是配置环境变量 写xxx.properties文件 是为了方便以后项目完成后,在不改变源码的情

Java Web项目经常提示错误

Java Web项目经常提示错误"This project needs to migrate WTP metadata",简单的解决方法就是右击项目然后选择Validate,做完validate后错误就消失了. 出处:http://stevex.blog.51cto.com/4300375/941669

eclipse上搭建maven多模块Java Web项目

1.模块化需求及项目模块说明 手头上有个已上线的系统,但因老板的特殊要求,系统需要不断的修改.还有就是公司市场部不定期地在举行一些微信活动,每一个活动都是周期性的,活动完了这个功能就要在系统中移除. 系统中就有三种模块:已经在系统中正常运行不需要再变更的模块.经常性变更的模块.用完就要移除的活动模块. 所以,我们需要把项目分成了下面几个模块. 简单说明一下: timetable-common是常用工具包存放的模块. wechat-api是微信接口模块,此模块用到了timetable-common

Java Web项目中使用Socket通信多线程、长连接的方法_java

很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接如一个硬件设备,通过tcp通信,获取设备传上来的数据,并对数据做回应. 先看一下web的监听代码: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class