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

本贴最后更新于 2635 天前,其中的信息可能已经时移世易
  • 使用 Nginx 作为前端接入

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

    遵守 KISS 原则(Keep it simple and stupid)。尽量不要考虑项目外的重用。过多的考虑项目外的重用,必然会增加项目的复杂度。避免过度集成,让每个模块只做自己的事,这对于日后的维护和模块复用都有好处。
    
  • 精心设计缓存处理、毫不吝啬代码(对象、列表、片段)

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

    对于每个表来讲,聚集索引只有一个,利用好了,查询速度会有意想不到的提升效果。
    以 MySql 为例,InnoDB选取聚集索引参照列的顺序是
            1\. 如果声声明了主键(primary key),则这个列会被做为聚集索引;
            2\. 如果没有声明主键,则会用一个唯一且不为空的索引列做为主键,成为此表的聚集索引;
            3\. 上面二个条件都不满足,InnoDB会自己产生一个虚拟的聚集索引。
    
  1. CREATE TABLE timeline_raw (
  2. rawId bigint(20) NOT NULL AUTO_INCREMENT,
  3. uid bigint(20) DEFAULT NULL,
  4. did bigint(20) DEFAULT NULL,
  5. channelId char(1) NOT NULL DEFAULT '1' COMMENT '1:qvga; 2:720p',
  6. fileId bigint(20) DEFAULT NULL,
  7. sectionId bigint(20) DEFAULT NULL,
  8. headerFilePath varchar(120) DEFAULT NULL,
  9. startTime bigint(20) DEFAULT NULL,
  10. endTime bigint(20) DEFAULT NULL,
  11. updateTime datetime DEFAULT NULL,
  12. createTime datetime DEFAULT NULL,
  13. PRIMARY KEY (rawId),
  14. KEY index_uid_did_startTime (uid,did,startTime) USING BTREE,
  15. KEY index_uid_did_endTime (uid,did,endTime) USING BTREE,
  16. KEY index_time (startTime) USING BTREE,
  17. KEY index_uid_did_fileId (uid,did,sectionId) USING BTREE,
  18. KEY index_sectionId (sectionId)
  19. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

这个表有四个索引:主键 rawId、sectionId、uid,did、startTime。
项目的 iBatis2 中有这样一条查询语句:

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

  2.  SELECT * FROM timeline_raw_  
    
  3.  WHERE uid=#uid#   
    
  4.  AND did=#did#   
    
  5.  AND channelId=#channelId#  
    
  6.  < isNotNull  property="sectionId"> AND sectionId = #sectionId# < isNotNull>  
    
  7.  AND   
    
  8.  (  
    
  9.          (startTime BETWEEN #startTime# and #endTime#)   
    
  10.              OR   
    
  11.          (endTime BETWEEN #startTime# and #endTime#)  
    
  12.                                      OR  
    
  13.       (  
    
  14.       startTime<=#startTime#  
    
  15.        ]]>   
    
  16.       AND   
    
  17.       endTime>=#endTime# 
    
  18.       ]]>   
    
  19.       )  
    
  20.  )  
    
  21.  ORDER BY startTime;   
    
  22. select>

    根据实际业务向 timeline_raw 表注入一千万条数据,进行模拟测试,发现 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 性能测试例子](http://blog.csdn.net/defonds/article/details/16832081)》。
    
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3169 引用 • 8207 回帖
  • Web
    115 引用 • 431 回帖 • 8 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • eddy

    学习了

  • 其他回帖
  • hanson08

    很受用!!!

推荐标签 标签

  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 80 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    138 引用 • 268 回帖 • 184 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 703 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    76 引用 • 37 回帖
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    35 引用 • 35 回帖
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    5 引用 • 15 回帖 • 209 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 474 关注
  • 安全

    安全永远都不是一个小问题。

    189 引用 • 813 回帖
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    164 引用 • 594 回帖 • 1 关注
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    165 引用 • 1461 回帖
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 233 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 294 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 23 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    675 引用 • 535 回帖
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 445 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 42 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    941 引用 • 1458 回帖 • 138 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 549 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 2 关注
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 44 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 519 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    21 引用 • 37 回帖 • 512 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 395 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 56 关注