性能优化基本是 BAT 等一线互联网公司程序员必备的技能, 以下为大家完整揭晓性能完整的优化方案和方法: 包含 web 网站调优, 数据库, JVM 调优, 架构调优等方案.
第一: Web 网站调优
1, 尽可能减少 HTTP 请求: 图片合并 (CSS sprites),JS 脚本文件合并, CSS 文件合并.
2, 减少 DNS 查询
3, 将 CSS 放在页面最上面, 将 JS 放在页面最下面
4, 压缩 JS 和 CSS
减少文件体积, 去除不必要的空白符, 格式符, 注释(即对代码进行格式化)
5, 把 JS 和 CSS 提取出来放在外部文件中
这一条要灵活运用, 把 JS 和 CSS 提取出来放在外部文件的优点是: 减少 html 体积, 提高了 JS 和 CSS 的复用性, 提高日后的可维护性
缺点: 增加了 http 请求, 不过这一点可以通过缓存来解决.
什么情况下将 JS 和 CSS 写在页面内呢, 可以分为几种情况: JS 和 CSS 代码比较少; 这个页面不怎么会访问
6, 避免重定向
重定向就是用户请求的页面被转移到了别的地方, 浏览器向服务请请求一个页面, 服务器告诉浏览器请求的页面已经被转移到另外一个页面, 并告知另一个页面地址, 浏览器就再发送请求到重定向的地址. 这样会增加服务器和浏览器之间的往返次数, 影响网站性能.
重定向状态码有: 301 永久重定向 302 临时重定向. 304 not modified 并不是真的重定向, 它是用来告诉浏览器 get 请求的文件在缓存中, 避免重新下载.
7, 移除重复脚本
8, 使用 Ajax 缓存
Ajax 的 get 和 post 方法:
只要是浏览器的 get 请求, 浏览器都会使用缓存, 对于同一地址的请求, 服务器会发送 304 状态码到浏览器, 浏览器就会使用缓存中的数据
post 的请求每次都会被执行, 浏览器不会缓存
9, 使用 Gzip 压缩
10, 使用 CDN(内容分发网络)
第二: 数据库调优
数据库的调优, 总的来说分为以下三部分:
1.SQL 调优: 主要集中在索引, 减少跨表与大数据 join 查询等.
2. 数据库端架构设计优化:
通过读写分离调整对数据库的写操作, 通过垂直拆分以及水平拆分 (分库分表) 来解决数据库端连接池瓶颈等问题.
3. 连接池调优
可以通过熟悉连接池的原理, 以及具体的连接池监控数据, 来不断调试出最终的连接池参数.
第三: 通过缓存减少后端压力
目前分布式缓存已经比较成熟, 常见的有 Redis,Memcached 以及开源的淘宝分布式 tair 等.
选型考虑
如果数据量小, 并且不会频繁地增长又清空(这会导致频繁地垃圾回收), 那么可以选择本地缓存. 具体的话, 如果需要一些策略的支持(比如缓存满的逐出策略), 可以考虑 Ehcache; 如不需要, 可以考虑 HashMap; 如需要考虑多线程并发的场景, 可以考虑 ConcurentHashMap.
缓存是否会满, 缓存满了怎么办?
对于一个缓存服务, 理论上来说, 随着缓存数据的日益增多, 在容量有限的情况下, 缓存肯定有一天会满的. 如何应对?
1 给缓存服务, 选择合适的缓存逐出算法, 比如最常见的 LRU.
2 针对当前设置的容量, 设置适当的警戒值, 比如 10G 的缓存, 当缓存数据达到 8G 的时候, 就开始发出报警, 提前排查问题或者扩容.
3 给一些没有必要长期保存的 key, 尽量设置过期时间.
第四: 数据请求改造为异步
使用场景
用户并不关心或者用户不需要立即拿到这些事情的处理结果, 这种情况就比较适合用异步的方式处理, 这里的原则就是能异步就异步.
常见做法
一种做法, 是额外开辟线程, 这里可以采用额外开辟一个线程或者使用线程池的做法, 在 IO 线程 (处理请求响应) 之外的线程来处理相应的任务, 在 IO 线程中让 response 先返回.
如果异步线程处理的任务设计的数据量非常巨大, 那么可以引入阻塞队列 BlockingQueue 作进一步的优化. 具体做法是让一批异步线程不断地往阻塞队列里扔数据, 然后额外起一个处理线程, 循环批量从队列里拿预设大小的一批数据, 来进行批处理(比如发一个批量的远程服务请求), 这样进一步提高了性能.
另一种做法, 是使用消息队列 (MQ) 中间件服务, MQ 天生就是异步的.
第五: JVM 调优
什么时候调?
通过监控系统对一些机器关键指标 (gc time,gc count, 各个分代的内存大小变化, 机器的 Load 值与 CPU 使用率, JVM 的线程数等) 的监控报警, 也可以看 gc log 和 jstat 等命令的输出, 再结合线上 JVM 进程服务的一些关键接口的性能数据和请求体验, 基本上就能定位出当前的 JVM 是否有问题, 以及是否需要调优.
调优工具:
Jconsole,jProfile,VisualVM
Jconsole :jdk 自带, 功能简单, 但是可以在系统有一定负荷的情况下使用. 对垃圾回收算法有很详细的跟踪. 详细说明参考这里
JProfiler: 商业软件, 需要付费. 功能强大. 详细说明参考这里
VisualVM:JDK 自带, 功能强大, 与 JProfiler 类似. 推荐.
如何调优?
观察内存释放情况, 集合类检查, 对象树
上面这些调优工具都提供了强大的功能, 但是总的来说一般分为以下几类功能
堆信息查看
可查看堆空间大小分配(年轻代, 年老代, 持久代分配)
性能优化基本是 BAT 等一线互联网公司程序员必备的技能, 以下为大家完整揭晓性能完整的优化方案和方法: 包含 Web 网站调优, 数据库, JVM 调优, 架构调优等方案.
第一: Web 网站调优
1, 尽可能减少 HTTP 请求: 图片合并 (CSS sprites),JS 脚本文件合并, CSS 文件合并.
2, 减少 DNS 查询
3, 将 CSS 放在页面最上面, 将 JS 放在页面最下面
4, 压缩 JS 和 CSS
减少文件体积, 去除不必要的空白符, 格式符, 注释(即对代码进行格式化)
5, 把 JS 和 CSS 提取出来放在外部文件中
这一条要灵活运用, 把 JS 和 CSS 提取出来放在外部文件的优点是: 减少 HTML 体积, 提高了 JS 和 CSS 的复用性, 提高日后的可维护性
缺点: 增加了 http 请求, 不过这一点可以通过缓存来解决.
什么情况下将 JS 和 CSS 写在页面内呢, 可以分为几种情况: JS 和 CSS 代码比较少; 这个页面不怎么会访问
6, 避免重定向
重定向就是用户请求的页面被转移到了别的地方, 浏览器向服务请请求一个页面, 服务器告诉浏览器请求的页面已经被转移到另外一个页面, 并告知另一个页面地址, 浏览器就再发送请求到重定向的地址. 这样会增加服务器和浏览器之间的往返次数, 影响网站性能.
重定向状态码有: 301 永久重定向 302 临时重定向. 304 not modified 并不是真的重定向, 它是用来告诉浏览器 get 请求的文件在缓存中, 避免重新下载.
7, 移除重复脚本
8, 使用 Ajax 缓存
Ajax 的 get 和 post 方法:
只要是浏览器的 get 请求, 浏览器都会使用缓存, 对于同一地址的请求, 服务器会发送 304 状态码到浏览器, 浏览器就会使用缓存中的数据
post 的请求每次都会被执行, 浏览器不会缓存
9, 使用 Gzip 压缩
10, 使用 CDN(内容分发网络)
第二: 数据库调优
数据库的调优, 总的来说分为以下三部分:
1.SQL 调优: 主要集中在索引, 减少跨表与大数据 join 查询等.
2. 数据库端架构设计优化:
通过读写分离调整对数据库的写操作, 通过垂直拆分以及水平拆分 (分库分表) 来解决数据库端连接池瓶颈等问题.
3. 连接池调优
可以通过熟悉连接池的原理, 以及具体的连接池监控数据, 来不断调试出最终的连接池参数.
第三: 通过缓存减少后端压力
目前分布式缓存已经比较成熟, 常见的有 Redis,Memcached 以及开源的淘宝分布式 tair 等.
选型考虑
如果数据量小, 并且不会频繁地增长又清空(这会导致频繁地垃圾回收), 那么可以选择本地缓存. 具体的话, 如果需要一些策略的支持(比如缓存满的逐出策略), 可以考虑 Ehcache; 如不需要, 可以考虑 HashMap; 如需要考虑多线程并发的场景, 可以考虑 ConcurentHashMap.
缓存是否会满, 缓存满了怎么办?
对于一个缓存服务, 理论上来说, 随着缓存数据的日益增多, 在容量有限的情况下, 缓存肯定有一天会满的. 如何应对?
1 给缓存服务, 选择合适的缓存逐出算法, 比如最常见的 LRU.
2 针对当前设置的容量, 设置适当的警戒值, 比如 10G 的缓存, 当缓存数据达到 8G 的时候, 就开始发出报警, 提前排查问题或者扩容.
3 给一些没有必要长期保存的 key, 尽量设置过期时间.
第四: 数据请求改造为异步
使用场景
用户并不关心或者用户不需要立即拿到这些事情的处理结果, 这种情况就比较适合用异步的方式处理, 这里的原则就是能异步就异步.
常见做法
一种做法, 是额外开辟线程, 这里可以采用额外开辟一个线程或者使用线程池的做法, 在 IO 线程 (处理请求响应) 之外的线程来处理相应的任务, 在 IO 线程中让 response 先返回.
如果异步线程处理的任务设计的数据量非常巨大, 那么可以引入阻塞队列 BlockingQueue 作进一步的优化. 具体做法是让一批异步线程不断地往阻塞队列里扔数据, 然后额外起一个处理线程, 循环批量从队列里拿预设大小的一批数据, 来进行批处理(比如发一个批量的远程服务请求), 这样进一步提高了性能.
另一种做法, 是使用消息队列 (MQ) 中间件服务, MQ 天生就是异步的.
第五: JVM 调优
什么时候调?
通过监控系统对一些机器关键指标 (gc time,gc count, 各个分代的内存大小变化, 机器的 Load 值与 CPU 使用率, JVM 的线程数等) 的监控报警, 也可以看 gc log 和 jstat 等命令的输出, 再结合线上 JVM 进程服务的一些关键接口的性能数据和请求体验, 基本上就能定位出当前的 JVM 是否有问题, 以及是否需要调优.
调优工具:
Jconsole,jProfile,VisualVM
Jconsole :jdk 自带, 功能简单, 但是可以在系统有一定负荷的情况下使用. 对垃圾回收算法有很详细的跟踪. 详细说明参考这里
JProfiler: 商业软件, 需要付费. 功能强大. 详细说明参考这里
VisualVM:JDK 自带, 功能强大, 与 JProfiler 类似. 推荐.
如何调优?
观察内存释放情况, 集合类检查, 对象树
上面这些调优工具都提供了强大的功能, 但是总的来说一般分为以下几类功能
堆信息查看
可查看堆空间大小分配(年轻代, 年老代, 持久代分配)
性能优化基本是 BAT 等一线互联网公司程序员必备的技能, 以下为大家完整揭晓性能完整的优化方案和方法: 包含 Web 网站调优, 数据库, JVM 调优, 架构调优等方案.
第一: Web 网站调优
1, 尽可能减少 HTTP 请求: 图片合并 (CSS sprites),JS 脚本文件合并, CSS 文件合并.
2, 减少 DNS 查询
3, 将 CSS 放在页面最上面, 将 JS 放在页面最下面
4, 压缩 JS 和 CSS
减少文件体积, 去除不必要的空白符, 格式符, 注释(即对代码进行格式化)
5, 把 JS 和 CSS 提取出来放在外部文件中
这一条要灵活运用, 把 JS 和 CSS 提取出来放在外部文件的优点是: 减少 HTML 体积, 提高了 JS 和 CSS 的复用性, 提高日后的可维护性
缺点: 增加了 http 请求, 不过这一点可以通过缓存来解决.
什么情况下将 JS 和 CSS 写在页面内呢, 可以分为几种情况: JS 和 CSS 代码比较少; 这个页面不怎么会访问
6, 避免重定向
重定向就是用户请求的页面被转移到了别的地方, 浏览器向服务请请求一个页面, 服务器告诉浏览器请求的页面已经被转移到另外一个页面, 并告知另一个页面地址, 浏览器就再发送请求到重定向的地址. 这样会增加服务器和浏览器之间的往返次数, 影响网站性能.
重定向状态码有: 301 永久重定向 302 临时重定向. 304 not modified 并不是真的重定向, 它是用来告诉浏览器 get 请求的文件在缓存中, 避免重新下载.
7, 移除重复脚本
8, 使用 Ajax 缓存
Ajax 的 get 和 post 方法:
只要是浏览器的 get 请求, 浏览器都会使用缓存, 对于同一地址的请求, 服务器会发送 304 状态码到浏览器, 浏览器就会使用缓存中的数据
post 的请求每次都会被执行, 浏览器不会缓存
9, 使用 Gzip 压缩
10, 使用 CDN(内容分发网络)
第二: 数据库调优
数据库的调优, 总的来说分为以下三部分:
1.SQL 调优: 主要集中在索引, 减少跨表与大数据 join 查询等.
2. 数据库端架构设计优化:
通过读写分离调整对数据库的写操作, 通过垂直拆分以及水平拆分 (分库分表) 来解决数据库端连接池瓶颈等问题.
3. 连接池调优
可以通过熟悉连接池的原理, 以及具体的连接池监控数据, 来不断调试出最终的连接池参数.
第三: 通过缓存减少后端压力
目前分布式缓存已经比较成熟, 常见的有 Redis,Memcached 以及开源的淘宝分布式 tair 等.
选型考虑
如果数据量小, 并且不会频繁地增长又清空(这会导致频繁地垃圾回收), 那么可以选择本地缓存. 具体的话, 如果需要一些策略的支持(比如缓存满的逐出策略), 可以考虑 Ehcache; 如不需要, 可以考虑 HashMap; 如需要考虑多线程并发的场景, 可以考虑 ConcurentHashMap.
缓存是否会满, 缓存满了怎么办?
对于一个缓存服务, 理论上来说, 随着缓存数据的日益增多, 在容量有限的情况下, 缓存肯定有一天会满的. 如何应对?
1 给缓存服务, 选择合适的缓存逐出算法, 比如最常见的 LRU.
2 针对当前设置的容量, 设置适当的警戒值, 比如 10G 的缓存, 当缓存数据达到 8G 的时候, 就开始发出报警, 提前排查问题或者扩容.
3 给一些没有必要长期保存的 key, 尽量设置过期时间.
第四: 数据请求改造为异步
使用场景
用户并不关心或者用户不需要立即拿到这些事情的处理结果, 这种情况就比较适合用异步的方式处理, 这里的原则就是能异步就异步.
常见做法
一种做法, 是额外开辟线程, 这里可以采用额外开辟一个线程或者使用线程池的做法, 在 IO 线程 (处理请求响应) 之外的线程来处理相应的任务, 在 IO 线程中让 response 先返回.
如果异步线程处理的任务设计的数据量非常巨大, 那么可以引入阻塞队列 BlockingQueue 作进一步的优化. 具体做法是让一批异步线程不断地往阻塞队列里扔数据, 然后额外起一个处理线程, 循环批量从队列里拿预设大小的一批数据, 来进行批处理(比如发一个批量的远程服务请求), 这样进一步提高了性能.
另一种做法, 是使用消息队列 (MQ) 中间件服务, MQ 天生就是异步的.
第五: JVM 调优
什么时候调?
通过监控系统对一些机器关键指标 (gc time,gc count, 各个分代的内存大小变化, 机器的 Load 值与 CPU 使用率, JVM 的线程数等) 的监控报警, 也可以看 gc log 和 jstat 等命令的输出, 再结合线上 JVM 进程服务的一些关键接口的性能数据和请求体验, 基本上就能定位出当前的 JVM 是否有问题, 以及是否需要调优.
调优工具:
Jconsole,jProfile,VisualVM
Jconsole :jdk 自带, 功能简单, 但是可以在系统有一定负荷的情况下使用. 对垃圾回收算法有很详细的跟踪. 详细说明参考这里
JProfiler: 商业软件, 需要付费. 功能强大. 详细说明参考这里
VisualVM:JDK 自带, 功能强大, 与 JProfiler 类似. 推荐.
如何调优?
观察内存释放情况, 集合类检查, 对象树
上面这些调优工具都提供了强大的功能, 但是总的来说一般分为以下几类功能
堆信息查看
可查看堆空间大小分配(年轻代, 年老代, 持久代分配)
提供即时的垃圾回收功能
垃圾监控(长时间监控回收情况)
查看堆内类, 对象信息查看: 数量, 类型等
对象引用情况查看
有了堆信息查看方面的功能, 我们一般可以顺利解决以下问题:
-- 年老代年轻代大小划分是否合理
-- 内存泄漏
-- 垃圾回收算法设置是否合理
线程监控
线程信息监控: 系统线程数量.
线程状态监控: 各个线程都处在什么样的状态下
Dump 线程详细信息: 查看线程内部运行情况
死锁检查
热点分析
CPU 热点: 检查系统哪些方法占用的大量 CPU 时间
内存热点: 检查哪些对象在系统中数量最大(一定时间内存活对象和销毁对象一起统计)
这两个东西对于系统优化很有帮助. 我们可以根据找到的热点, 有针对性的进行系统的瓶颈查找和进行系统优化, 而不是漫无目的的进行所有代码的优化.
快照
快照是系统运行到某一时刻的一个定格. 在我们进行调优的时候, 不可能用眼睛去跟踪所有系统变化, 依赖快照功能, 我们就可以进行系统两个不同运行时刻, 对象 (或类, 线程等) 的不同, 以便快速找到问题
举例说, 我要检查系统进行垃圾回收以后, 是否还有该收回的对象被遗漏下来的了. 那么, 我可以在进行垃圾回收前后, 分别进行一次堆情况的快照, 然后对比两次快照的对象情况.
内存泄漏检查
内存泄漏是比较常见的问题, 而且解决方法也比较通用, 这里可以重点说一下, 而线程, 热点方面的问题则是具体问题具体分析了.
内存泄漏一般可以理解为系统资源 (各方面的资源, 堆, 栈, 线程等) 在错误使用的情况下, 导致使用完毕的资源无法回收(或没有回收), 从而导致新的资源分配请求无法完成, 引起系统错误.
内存泄漏对系统危害比较大, 因为他可以直接导致系统的崩溃.
性能调优总结:
大型网站的性能瓶颈大部分瓶颈都在数据库端, 所以性能调优总是沿着如何减少对后端的压力来操作, 数据库端的瓶颈经常会造成应用端的雪崩 (比如: sql 查询过长, 长事务) 等, 所以需要及时解决后端性能.
1. 通过读写分离, 垂直拆分, 水平拆分降低对数据库后端的压力.
2. 通过优化 sql 语句, 索引等, 缩短对 sql 的查询时间.
2. 通过缓存以及 CDN 来解决对图片, 文件等的读操作, 避免对数据库产生压力.
3. 通过对 Web 端的优化, JS,CSS 等压缩, 提高大文件读取时间, 尽量依赖 CDN.
4. 还有一个重点就是监控: 对 JVM, 线程, sql 查询时间等健康指标就行及时监控, 通过监控及时发现瓶颈, 及时优化.
来源: http://www.bubuko.com/infodetail-3297131.html