Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

01 | 如何制定性能调优标准?

刘超 2019-05-21
你好,我是刘超。
我有一个朋友,有一次他跟我说,他们公司的系统从来没有经过性能调优,功能测试完成后就上线了,线上也没有出现过什么性能问题呀,那为什么很多系统都要去做性能调优呢?
当时我就回答了他一句,如果你们公司做的是 12306 网站,不做系统性能优化就上线,试试看会是什么情况。
如果是你,你会怎么回答呢?今天,我们就从这个话题聊起,希望能跟你一起弄明白这几个问题:我们为什么要做性能调优?什么时候开始做?做性能调优是不是有标准可参考?

为什么要做性能调优?

一款线上产品如果没有经过性能测试,那它就好比是一颗定时炸弹,你不知道它什么时候会出现问题,你也不清楚它能承受的极限在哪儿。
有些性能问题是时间累积慢慢产生的,到了一定时间自然就爆炸了;而更多的性能问题是由访问量的波动导致的,例如,活动或者公司产品用户量上升;当然也有可能是一款产品上线后就半死不活,一直没有大访问量,所以还没有引发这颗定时炸弹。
现在假设你的系统要做一次活动,产品经理或者老板告诉你预计有几十万的用户访问量,询问系统能否承受得住这次活动的压力。如果你不清楚自己系统的性能情况,也只能战战兢兢地回答老板,有可能大概没问题吧。
所以,要不要做性能调优,这个问题其实很好回答。所有的系统在开发完之后,多多少少都会有性能问题,我们首先要做的就是想办法把问题暴露出来,例如进行压力测试、模拟可能的操作场景等等,再通过性能调优去解决这些问题。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(70)

  • 杨军
    首先很高兴终于有人开Java性能优化的课程,我在工作中需要接触很多这方面的工作,希望通过学习这次课程能带来更多收获。
    然后我想请教老师一个问题,CPU利用率和系统负载这两个指标之间是什么关系?网上很多资料讲的不清不楚,看不明白。

    作者回复: 杨军你好,系统负载代表单位时间内正在运行或等待的进程或线程数,代表了系统的繁忙程度,CPU利用率则代表单位时间内一个线程或进程实时占用CPU的百分比。我们知道,一个进程或者线程在运行时,未必都在实时的利用CPU的。

    比如,在CPU密集型的情况下,系统的负载未必会高,但CPU的利用率肯定会高,一个线程/进程一直在计算,它对CPU的实时利用率是100%,而系统负载是0.1;

    又比如,而对于I/O密集型的程序来说,有可能CPU的利用率不高,但系统的负载却会非常高,这是因为I/O经常引起阻塞,这样导致很多线程/进程被处于阻塞等待状态,处于等待的线程或进程也是属于负载线程/进程的。

    通过以上两个例子,不知道有没有让你分清楚两个指标的区别,有问题保持沟通。

    2019-05-21
    55
  • 遇见阳光
    老师,tps qps这块还是有点不太清楚。

    作者回复: 遇见阳光 你好,TPS(transaction per second)是单位时间内处理事务的数量,QPS(query per second)是单位时间内请求的数量。TPS代表一个事务的处理,可以包含了多次请求。很多公司用QPS作为接口吞吐量的指标,也有很多公司使用TPS作为标准,两者都能表现出系统的吞吐量的大小,TPS的一次事务代表一次用户操作到服务器返回结果,QPS的一次请求代表一个接口的一次请求到服务器返回结果。当一次用户操作只包含一个请求接口时,TPS和QPS没有区别。当用户的一次操作包含了多个服务请求时,这个时候TPS作为这次用户操作的性能指标就更具有代表性了。

    2019-05-21
    18
  • Maxwell
    请问老师最近段时间遇到端口被CLOSE_WAIT占用,重启后过了半天又重现,以前没有出现过,一般如何排查

    作者回复: 可以通过tcpdump抓包看看连接状态,分析是否是服务端的FIN packet没有发出去。

    正常的关闭流程是:服务端在接收到客户端发送的关闭请求FIN后,会进入CLOSE_WAIT状态,同时发送ACK回去。在完成与客户端直接的通信操作之后,再向客户端发送FIN,进入LAST_ACK状态。

    如果连接是CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Client,那么可能是在关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。

    建议确定关闭请求的四次握手,哪个环节出了问题,再去排查业务代码,可能是由于超时或者异常导致没有正常关闭连接。

    2019-06-01
    14
  • QQ怪
    我觉得还有接口返回200的成功率吧

    作者回复: 晚上好 QQ怪,你说的很对。我们平时在使用AB进行压测时,会有一个failed requests指标,本身接口没有异常的情况下,压测出现了异常,也是说明这个接口有性能问题。还有就是percentage of the requests served within a certain time这个指标,这个指标对金融交易系统来说是非常重要的,如果有99%的请求是1ms返回,但有1%是500ms返回,这对于某些对交易时间要求极致的金融系统来说也是性能问题。感谢你的回答,期望我的回答能让你满意!

    2019-05-20
    14
  • kaixiao7
    老师,关于JVM的异常问题,您在@陆离的回答中说"平时的业务异常避免生成栈追踪信息,在异常中用字符串描述业务异常信息即可",我通过throw new Exception("aaa"),debug时发现还是会调用fillInStackTrace()方法。我是不是理解错了呢?具体该怎么做?感谢

    作者回复: 可以自己实现自定义异常,继承RuntimeException,然后将writableStackTrace设置为false。

    以下是RuntimeException的构造函数:

    protected RuntimeException(String message, Throwable cause,
                                   boolean enableSuppression,
                                   boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }

    2019-06-04
    11
  • 诸葛
    异常:Java 应用中,抛出异常需要构建异常栈,对异常进行捕获和处理,这个过程非常消耗系统性能。如果在高并发的情况下引发异常,持续地进行异常处理,那么系统的性能就会明显地受到影响。
    老师好,高并发调用方法之后第一步就是检验一堆入参,如果入参有问题立即抛出异常给前端,不再处理下边的逻辑了,这样有问题吗?我看系统性能还可以啊。压力测试也还行。如果有问题的话那应该怎么做呢,检验错误后给前端放回code码然后返回空对象吗?感谢

    作者回复: 如果没有生成堆栈追踪信息,不会有性能问题。一般业务异常避免生成堆栈追踪信息,我们知道这个异常是什么原因,所以直接返回字符串就好了。而系统异常,一般都会生成堆栈追踪信息,以便追踪源头,更好的排查问题。

    2019-05-26
    6
  • 业余草
    优化,首先是你要知道它是什么,用了什么原理,才能更深入的去做好优化。其实最重要的优化,是优化自己的编程思想。首先要排除的是,每个需求,不是功能做完了就做好了。我们要做的是把知识变成钱,而不是把劳动力变成钱,😊
    2019-05-21
    5
  • Phoenix
    想请教下老师,使用MySQL经常会遇到业务需要实时导出大量业务数据的需求,那么如何在不影响业务和不分库的的情况满足业务实时导出大量数据的需求呢?

    作者回复: 你好 Phoenix,切忌在主库中操作这种报表类的导出,在写入和查询都在一个主库进行,会造成数据库性能瓶颈,严重的会导致数据库死锁。我们可以将数据库读写分离,写业务走主(写)库,导出数据可以从从(读)库导出。这种实现方式,首先能提高数据导出的性能,其次不影响写业务。

    如果你们公司有大数据中心,可以考虑将需要导出的数据实时同步到大数据中心,通过实时的流计算处理生成不同需求的业务数据。

    希望以上的回答能让你满意,如果有问题保持沟通!

    2019-05-20
    4
  • 小辉辉
    现在的项目也是没有经过压测和调优的,上线也没多久,正好跟着老师的专栏来试着优化一下性能😁😁😁

    编辑回复: 为你手动点赞👍🏻

    2019-05-20
    3
  • Teamillet
    编译原理还好没忘记,少用正则……
    2019-05-30
    2
  • 随遇而安
    希望这次能学到真正的东西

    编辑回复: 坚持就会有收获,加油!

    2019-05-20
    2
  • 我行我素
    并发用户数,高可用可扩展等方面

    作者回复: 你好 我行我素,感谢你的回答。并发用户数代表系统同一时间处理事务的并发能力,也是体现系统性能的一个直接性能指标。当然,TPS也能间接的体现系统并发处理能力。

    2019-05-20
    2
  • Seal
    我经常关注的一个性能指标还有QPS(每秒请求数),它体现了服务端对接口的处理能力。在响应时间一定的情况下,QPS越大,性能越高! 每个应用服务都有自己最大的QPS值,当QPS达到最大时,再持续加压,将会出现响应时间变长,QPS下降,内存或CPU升高等现象!

    作者回复: 你好 Seal,你的描述很准确,QPS/TPS这两个性能指标非常相似,都是描述吞吐量的性能指标,QPS特指的一次查询请求,TPS是指每次处理事务请求,TPS包括了QPS,例如一个事务处理可能包括多个查询请求。

    2019-05-20
    2
  • SlamDunk
    请问,我们公司业务代码对异常的处理方式:先打印异常堆栈信息到日志文件,再返回错误码和业务错误信息给前端。这种做法对性能影响大吗?

    作者回复: 偶尔一两次异常情况是不会影响系统的性能,但在峰值出现大量请求异常,会影响到系统性能。

    建议查看下是否重写了业务的异常。我们一般在定义业务异常时可以自己实现自定义异常,继承RuntimeException,然后将writableStackTrace设置为false。



    以下是RuntimeException的构造函数:

    protected RuntimeException(String message, Throwable cause,
                                   boolean enableSuppression,
                                   boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }

    2019-06-07
    1
  • Geek_ebda96
    老师你好,请问系统负载所指的正在运行或者等待的进程数和CPU的数目的百分比,但我大部分得系统来说运行的进程数目基本不会边,都是稳定的,在变的应该是应用程序本身的线程数,这个参数对于性能观察来说有用么,哪些方法能看到因为线程数过多或者线程的使用率很高导致性能问题,比如TOP查看CPU使用率?

    作者回复: 进程或线程,不单单指的是进程。可用使用top指令查看整体的使用率以及单个进程和单个线程的使用率。

    2019-05-28
    1
    1
  • 张小小的席大大
    老师 您好 我想请问个问题 您说的压测工具ab 我用过 但是我们现在想要模拟完整的项目流程去压测(直播项目) 您有什么好的建议么

    作者回复: 建议使用jmeter或者loadrunner,可以通过录制业务流程,生成jmeter脚本。近期我会讲到测试工具的使用。

    2019-05-28
    1
  • ty_young
    老师,TPS是应用处理的性能指标吧,然后由磁盘吞吐量和网络吞吐量所决定或者影响么

    作者回复: 这位同学,你好。我们这里描述的三种吞吐量,一个是应用服务的吞吐量,然后就是磁盘和网络吞吐量。上述描述不是在强调磁盘和网络吞吐量决定了应用服务的吞吐量的必然关系。在某些情况下,磁盘的吞吐量和网络的吞吐量会影响我们应用服务的吞吐量。而在磁盘性能以及网络带宽合理的情况下,两者对应用服务吞吐量的影响是最小的。

    以上我的解释希望能帮你更好的理解,有问题保持沟通。

    2019-05-22
    1
  • 行者
    老师,我想到服务器响应时间可以进一步细分到服务器中位数响应时间,服务器最慢的响应时间;要尽可能让所有接口响应时间接近,避免长尾。

    作者回复: 行者你好,你想到的很好,我们在做性能测试的时候有一个percentage of the requests served within a certain time指标,就是反应单位时间内,不同响应时间的占比率,例如50% 的响应时间是1ms以内,80%的响应时间是2ms以内,99%的响应时间是5ms以内。说明有19%是在2ms~5ms以内,如果这个范围太大,有可能存在性能问题,具体问题具体分析。

    上述我说的这个参数应该就是你现在描述的性能指标,有问题保持沟通。

    2019-05-22
    1
  • tyul
    网络吞吐量里面的字被和谐了

    编辑回复: 感谢这位热心同学!

    2019-05-22
    1
  • 庄风
    希望老师在以后的课程中讲一下相关性能监测工具软件。我在项目中遇到了性能问题后,确实不知道该如何分析、监测系统状态,并进行相应的处理和优化。之前一直用的是Windows自带的性能监视器,不过并不好用。
    2019-05-22
    1
收起评论
70
返回
顶部